diff --git a/enterprise/micronaut/nbproject/project.xml b/enterprise/micronaut/nbproject/project.xml
index 1b39c39dfa16..4454124894e4 100644
--- a/enterprise/micronaut/nbproject/project.xml
+++ b/enterprise/micronaut/nbproject/project.xml
@@ -57,7 +57,7 @@
1
- 1.23
+ 1.24
diff --git a/enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionCollector.java b/enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionCollector.java
index 53067455be8c..c7429133135f 100644
--- a/enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionCollector.java
+++ b/enterprise/micronaut/src/org/netbeans/modules/micronaut/completion/MicronautDataCompletionCollector.java
@@ -74,9 +74,9 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
ExecutableType type = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) delegateRepositoryType, delegateMethod);
Iterator extends VariableElement> it = delegateMethod.getParameters().iterator();
Iterator extends TypeMirror> tIt = type.getParameterTypes().iterator();
- StringBuilder label = new StringBuilder();
+ StringBuilder labelDetail = new StringBuilder();
StringBuilder sortParams = new StringBuilder();
- label.append(methodName).append("(");
+ labelDetail.append("(");
sortParams.append('(');
int cnt = 0;
while(it.hasNext() && tIt.hasNext()) {
@@ -87,15 +87,15 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, delegateMethod.isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
- label.append(paramTypeName).append(' ').append(paramName);
+ labelDetail.append(paramTypeName).append(' ').append(paramName);
sortParams.append(paramTypeName);
if (tIt.hasNext()) {
- label.append(", ");
+ labelDetail.append(", ");
sortParams.append(',');
}
}
sortParams.append(')');
- label.append(')');
+ labelDetail.append(')');
TypeMirror returnType = type.getReturnType();
if ("findAll".contentEquals(delegateMethod.getSimpleName()) && !delegateMethod.getParameters().isEmpty() && returnType.getKind() == TypeKind.DECLARED) {
TypeElement te = (TypeElement) ((DeclaredType) returnType).asElement();
@@ -104,12 +104,13 @@ public Completion createControllerMethodItem(CompilationInfo info, VariableEleme
returnType = (ExecutableType) info.getTypes().asMemberOf((DeclaredType) returnType, getContentMethod.get());
}
}
- label.append(" : ").append(MicronautDataCompletionTask.getTypeName(info, returnType, false, false));
FileObject fo = info.getFileObject();
ElementHandle repositoryHandle = ElementHandle.create(delegateRepository);
ElementHandle methodHandle = ElementHandle.create(delegateMethod);
- return CompletionCollector.newBuilder(String.format("%s - generate", label.toString()))
+ return CompletionCollector.newBuilder(methodName)
.kind(Completion.Kind.Method)
+ .labelDetail(String.format("%s - generate", labelDetail.toString()))
+ .labelDescription(MicronautDataCompletionTask.getTypeName(info, returnType, false, false).toString())
.sortText(String.format("%04d%s#%02d%s", 1500, methodName, cnt, sortParams.toString()))
.insertTextFormat(Completion.TextFormat.PlainText)
.textEdit(new TextEdit(offset, offset, ""))
@@ -203,11 +204,11 @@ public Completion createJavaElementItem(CompilationInfo info, Element element, i
if (element.getKind() == ElementKind.METHOD) {
Iterator extends VariableElement> it = ((ExecutableElement)element).getParameters().iterator();
Iterator extends TypeMirror> tIt = ((ExecutableType) element.asType()).getParameterTypes().iterator();
- StringBuilder label = new StringBuilder();
+ StringBuilder labelDetail = new StringBuilder();
StringBuilder insertText = new StringBuilder();
StringBuilder sortParams = new StringBuilder();
- label.append(simpleName).append("(");
- insertText.append(simpleName).append("(");
+ labelDetail.append('(');
+ insertText.append(simpleName).append('(');
sortParams.append('(');
int cnt = 0;
boolean asTemplate = false;
@@ -219,21 +220,23 @@ public Completion createJavaElementItem(CompilationInfo info, Element element, i
cnt++;
String paramTypeName = MicronautDataCompletionTask.getTypeName(info, tm, false, ((ExecutableElement)element).isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
- label.append(paramTypeName).append(' ').append(paramName);
+ labelDetail.append(paramTypeName).append(' ').append(paramName);
sortParams.append(paramTypeName);
- insertText.append("${").append(cnt).append(":").append(paramName).append("}");
+ insertText.append("${").append(cnt).append(':').append(paramName).append('}');
asTemplate = true;
if (tIt.hasNext()) {
- label.append(", ");
+ labelDetail.append(", ");
sortParams.append(',');
insertText.append(", ");
}
}
- label.append(") : ").append(MicronautDataCompletionTask.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString());
+ labelDetail.append(')');
insertText.append(')');
sortParams.append(')');
- return CompletionCollector.newBuilder(label.toString())
+ return CompletionCollector.newBuilder(simpleName)
.kind(Completion.Kind.Method)
+ .labelDetail(labelDetail.toString())
+ .labelDescription(MicronautDataCompletionTask.getTypeName(info, ((ExecutableElement)element).getReturnType(), false, false).toString())
.sortText(String.format("%04d%s#%02d%s", 100, simpleName, cnt, sortParams.toString()))
.insertText(insertText.toString())
.insertTextFormat(asTemplate ? Completion.TextFormat.Snippet : Completion.TextFormat.PlainText)
diff --git a/ide/api.lsp/apichanges.xml b/ide/api.lsp/apichanges.xml
index ec9840031537..d535b3a99344 100644
--- a/ide/api.lsp/apichanges.xml
+++ b/ide/api.lsp/apichanges.xml
@@ -51,6 +51,22 @@
+
+
+ Added Completion.getLabelDetail() and Completion.getLabelDescription() methods.
+
+
+
+
+
+ Completion.getLabelDetail()
+ to get an optional string describing function signatures or type annotations.
+ Completion.getLabelDescription()
+ to get an optional string describing fully qualified names or file path.
+
+
+
+
Added CodeActionProvider interface
@@ -108,13 +124,13 @@
- Added URL to diagnostic code description
+ Added Completion.getCommand() to get an optional command
- Completion.getCommand to get an optional command
+ Completion.getCommand() to get an optional command
that is executed after inserting the completion.
diff --git a/ide/api.lsp/manifest.mf b/ide/api.lsp/manifest.mf
index 2eaadac4f965..5ac5b8f3334f 100644
--- a/ide/api.lsp/manifest.mf
+++ b/ide/api.lsp/manifest.mf
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.api.lsp/1
OpenIDE-Module-Localizing-Bundle: org/netbeans/api/lsp/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.23
+OpenIDE-Module-Specification-Version: 1.24
AutoUpdate-Show-In-Client: false
diff --git a/ide/api.lsp/src/org/netbeans/api/lsp/Completion.java b/ide/api.lsp/src/org/netbeans/api/lsp/Completion.java
index 072f9832a96b..142ebf2239db 100644
--- a/ide/api.lsp/src/org/netbeans/api/lsp/Completion.java
+++ b/ide/api.lsp/src/org/netbeans/api/lsp/Completion.java
@@ -43,15 +43,17 @@ public final class Completion {
static {
CompletionAccessor.setDefault(new CompletionAccessor() {
@Override
- public Completion createCompletion(String label, Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
+ public Completion createCompletion(String label, String labelDetail, String description, Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
boolean preselect, String sortText, String filterText, String insertText, TextFormat insertTextFormat, TextEdit textEdit, Command command,
CompletableFuture> additionalTextEdits, List commitCharacters) {
- return new Completion(label, kind, tags, detail, documentation, preselect, sortText, filterText, insertText, insertTextFormat, textEdit, command, additionalTextEdits, commitCharacters);
+ return new Completion(label, labelDetail, description, kind, tags, detail, documentation, preselect, sortText, filterText, insertText, insertTextFormat, textEdit, command, additionalTextEdits, commitCharacters);
}
});
}
private final String label;
+ private final String labelDetail;
+ private final String labelDescription;
private final Kind kind;
private final List tags;
private final CompletableFuture detail;
@@ -66,10 +68,12 @@ public Completion createCompletion(String label, Kind kind, List tags, Comp
private final CompletableFuture> additionalTextEdits;
private final List commitCharacters;
- private Completion(String label, Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
+ private Completion(String label, String labelDetail, String labelDescription, Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
boolean preselect, String sortText, String filterText, String insertText, TextFormat insertTextFormat,
TextEdit textEdit, Command command, CompletableFuture> additionalTextEdits, List commitCharacters) {
this.label = label;
+ this.labelDetail = labelDetail;
+ this.labelDescription = labelDescription;
this.kind = kind;
this.tags = tags;
this.detail = detail;
@@ -96,6 +100,30 @@ public String getLabel() {
return label;
}
+ /**
+ * An optional string which is rendered less prominently directly after
+ * {@link Completion#getLabel() label}, without any spacing. Should be
+ * used for function signatures or type annotations.
+ *
+ * @since 1.24
+ */
+ @CheckForNull
+ public String getLabelDetail() {
+ return labelDetail;
+ }
+
+ /**
+ * An optional string which is rendered less prominently after
+ * {@link Completion#getLabelDetail() label detail}. Should be used for fully qualified
+ * names or file path.
+ *
+ * @since 1.24
+ */
+ @CheckForNull
+ public String getLabelDescription() {
+ return labelDescription;
+ }
+
/**
* The kind of this completion.
*
diff --git a/ide/api.lsp/src/org/netbeans/modules/lsp/CompletionAccessor.java b/ide/api.lsp/src/org/netbeans/modules/lsp/CompletionAccessor.java
index 6a40e63554e8..e799f848e5af 100644
--- a/ide/api.lsp/src/org/netbeans/modules/lsp/CompletionAccessor.java
+++ b/ide/api.lsp/src/org/netbeans/modules/lsp/CompletionAccessor.java
@@ -55,7 +55,7 @@ public static void setDefault(@NonNull final CompletionAccessor accessor) {
DEFAULT = accessor;
}
- public abstract Completion createCompletion(String label, Completion.Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
+ public abstract Completion createCompletion(String label, String labelDetail, String labelDescription, Completion.Kind kind, List tags, CompletableFuture detail, CompletableFuture documentation,
boolean preselect, String sortText, String filterText, String insertText, Completion.TextFormat insertTextFormat,
TextEdit textEdit, Command command, CompletableFuture> additionalTextEdits, List commitCharacters);
}
diff --git a/ide/api.lsp/src/org/netbeans/spi/lsp/CompletionCollector.java b/ide/api.lsp/src/org/netbeans/spi/lsp/CompletionCollector.java
index 34b964ce0e79..79b497c324f0 100644
--- a/ide/api.lsp/src/org/netbeans/spi/lsp/CompletionCollector.java
+++ b/ide/api.lsp/src/org/netbeans/spi/lsp/CompletionCollector.java
@@ -90,6 +90,8 @@ public static Builder newBuilder(@NonNull String label) {
public static final class Builder {
private String label;
+ private String labelDetail;
+ private String labelDescription;
private Completion.Kind kind;
private List tags;
private CompletableFuture detail;
@@ -120,6 +122,32 @@ public Builder label(@NonNull String label) {
return this;
}
+ /**
+ * An optional string which is rendered less prominently directly after
+ * {@link Completion#getLabel() label}, without any spacing. Should be
+ * used for function signatures or type annotations.
+ *
+ * @since 1.24
+ */
+ @NonNull
+ public Builder labelDetail(@NonNull String labelDetail) {
+ this.labelDetail = labelDetail;
+ return this;
+ }
+
+ /**
+ * An optional string which is rendered less prominently after
+ * {@link Completion#getLabelDetail() label detail}. Should be used for fully qualified
+ * names or file path.
+ *
+ * @since 1.24
+ */
+ @NonNull
+ public Builder labelDescription(@NonNull String labelDescription) {
+ this.labelDescription = labelDescription;
+ return this;
+ }
+
/**
* The kind of this completion.
*
@@ -344,10 +372,10 @@ public Builder addCommitCharacter(char commitCharacter) {
*/
@NonNull
public Completion build() {
- return CompletionAccessor.getDefault().createCompletion(label, kind,
- tags, detail, documentation, preselect, sortText, filterText,
- insertText, insertTextFormat, textEdit, command, additionalTextEdits,
- commitCharacters);
+ return CompletionAccessor.getDefault().createCompletion(label, labelDetail,
+ labelDescription, kind, tags, detail, documentation, preselect, sortText,
+ filterText, insertText, insertTextFormat, textEdit, command,
+ additionalTextEdits, commitCharacters);
}
private static class LazyCompletableFuture extends CompletableFuture {
diff --git a/java/java.editor/nbproject/project.xml b/java/java.editor/nbproject/project.xml
index 42b86a983bc1..0b5a6e5d585a 100644
--- a/java/java.editor/nbproject/project.xml
+++ b/java/java.editor/nbproject/project.xml
@@ -58,7 +58,7 @@
1
- 1.20
+ 1.24
diff --git a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
index e3677c6a3bc8..8c0376cd22bf 100644
--- a/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
+++ b/java/java.editor/src/org/netbeans/modules/editor/java/JavaCompletionCollector.java
@@ -416,13 +416,13 @@ public Completion createTypeCastableVariableItem(CompilationInfo info, VariableE
int priority = elem.getKind() == ElementKind.ENUM_CONSTANT || elem.getKind() == ElementKind.FIELD ? smartType ? 300 : 1300 : smartType ? 200 : 1200;
StringBuilder label = new StringBuilder();
label.append(elem.getSimpleName());
- if (type != null) {
- label.append(" : ").append(Utilities.getTypeName(info, type, false));
- }
CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
.kind(elementKind2CompletionItemKind(elem.getKind()))
.sortText(String.format("%04d%s", priority, elem.getSimpleName().toString()))
.insertTextFormat(Completion.TextFormat.PlainText);
+ if (type != null) {
+ builder.labelDescription(Utilities.getTypeName(info, type, false).toString());
+ }
TextEdit textEdit = null;
String filter = null;
if (castType != null) {
@@ -491,8 +491,10 @@ public Completion createThisOrSuperConstructorItem(CompilationInfo info, Executa
@Override
public Completion createOverrideMethodItem(CompilationInfo info, ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean implement) {
Completion item = createExecutableItem(info, elem, type, substitutionOffset, null, false, false, false, false, false, -1, false);
- CompletionCollector.Builder builder = CompletionCollector.newBuilder(String.format("%s - %s", item.getLabel(), implement ? "implement" : "override"))
+ CompletionCollector.Builder builder = CompletionCollector.newBuilder(item.getLabel())
.kind(elementKind2CompletionItemKind(elem.getKind()))
+ .labelDetail(String.format("%s - %s", item.getLabelDetail(), implement ? "implement" : "override"))
+ .labelDescription(item.getLabelDescription())
.sortText(item.getSortText())
.insertTextFormat(Completion.TextFormat.PlainText)
.textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY))
@@ -515,9 +517,9 @@ public Completion createOverrideMethodItem(CompilationInfo info, ExecutableEleme
@Override
public Completion createGetterSetterMethodItem(CompilationInfo info, VariableElement elem, TypeMirror type, int substitutionOffset, String name, boolean setter) {
String typeName = Utilities.getTypeName(info, type, false).toString();
- StringBuilder label = new StringBuilder();
+ StringBuilder labelDetail = new StringBuilder();
StringBuilder sortParams = new StringBuilder();
- label.append(name).append('(');
+ labelDetail.append('(');
sortParams.append('(');
if (setter) {
CodeStyle cs = null;
@@ -536,16 +538,13 @@ public Completion createGetterSetterMethodItem(CompilationInfo info, VariableEle
simpleName,
cs.getParameterNamePrefix(),
cs.getParameterNameSuffix());
- label.append(typeName).append(' ').append(paramName);
+ labelDetail.append(typeName).append(' ').append(paramName);
sortParams.append(typeName);
}
- label.append(')');
- if (!setter) {
- label.append(": ").append(typeName);
- }
- label.append(" - generate");
- return CompletionCollector.newBuilder(label.toString())
+ labelDetail.append(") - generate");
+ Builder builder = CompletionCollector.newBuilder(name)
.kind(Completion.Kind.Method)
+ .labelDetail(labelDetail.toString())
.insertTextFormat(Completion.TextFormat.PlainText)
.sortText(String.format("%04d%s#%02d%s", 1500, name, setter ? 1 : 0, sortParams.toString()))
.textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY))
@@ -564,13 +563,18 @@ public Completion createGetterSetterMethodItem(CompilationInfo info, VariableEle
wc.rewrite(tp.getLeaf(), decl);
}
}
- })).build();
+ }));
+ if (!setter) {
+ builder.labelDescription(typeName);
+ }
+ return builder.build();
}
@Override
public Completion createDefaultConstructorItem(TypeElement elem, int substitutionOffset, boolean smartType) {
- Builder builder = CompletionCollector.newBuilder(elem.getSimpleName().toString() + "()")
+ Builder builder = CompletionCollector.newBuilder(elem.getSimpleName().toString())
.kind(Completion.Kind.Constructor)
+ .labelDetail("()")
.sortText(String.format("%04d%s#0", smartType ? 650 : 1650, elem.getSimpleName().toString()));
StringBuilder insertText = new StringBuilder();
if (substitutionOffset < offset) {
@@ -737,9 +741,9 @@ public Completion createChainedMembersItem(CompilationInfo info, List extends
@Override
public Completion createInitializeAllConstructorItem(CompilationInfo info, boolean isDefault, Iterable extends VariableElement> fields, ExecutableElement superConstructor, TypeElement parent, int substitutionOffset) {
String simpleName = parent.getSimpleName().toString();
- StringBuilder label = new StringBuilder();
+ StringBuilder labelDetail = new StringBuilder();
StringBuilder sortParams = new StringBuilder();
- label.append(simpleName).append('(');
+ labelDetail.append('(');
sortParams.append('(');
CodeStyle cs = null;
try {
@@ -753,7 +757,7 @@ public Completion createInitializeAllConstructorItem(CompilationInfo info, boole
if (!isDefault) {
for (VariableElement ve : fields) {
if (cnt > 0) {
- label.append(", ");
+ labelDetail.append(", ");
sortParams.append(",");
}
boolean isStatic = ve.getModifiers().contains(Modifier.STATIC);
@@ -765,14 +769,14 @@ public Completion createInitializeAllConstructorItem(CompilationInfo info, boole
cs.getParameterNamePrefix(),
cs.getParameterNameSuffix());
String paramTypeName = Utilities.getTypeName(info, ve.asType(), false).toString();
- label.append(paramTypeName).append(' ').append(sName);
+ labelDetail.append(paramTypeName).append(' ').append(sName);
sortParams.append(paramTypeName);
cnt++;
}
if (superConstructor != null) {
for (VariableElement ve : superConstructor.getParameters()) {
if (cnt > 0) {
- label.append(", ");
+ labelDetail.append(", ");
sortParams.append(",");
}
String sName = CodeStyleUtils.removePrefixSuffix(ve.getSimpleName(), cs.getParameterNamePrefix(), cs.getParameterNameSuffix());
@@ -781,16 +785,17 @@ public Completion createInitializeAllConstructorItem(CompilationInfo info, boole
cs.getParameterNamePrefix(),
cs.getParameterNameSuffix());
String paramTypeName = Utilities.getTypeName(info, ve.asType(), false).toString();
- label.append(paramTypeName).append(' ').append(sName);
+ labelDetail.append(paramTypeName).append(' ').append(sName);
sortParams.append(paramTypeName);
cnt++;
}
}
}
- label.append(") - generate");
+ labelDetail.append(") - generate");
sortParams.append(')');
- return CompletionCollector.newBuilder(label.toString())
+ return CompletionCollector.newBuilder(simpleName)
.kind(Completion.Kind.Constructor)
+ .labelDetail(labelDetail.toString())
.insertTextFormat(Completion.TextFormat.PlainText)
.sortText(String.format("%04d%s#%02d%s", 1400, simpleName, cnt, sortParams.toString()))
.textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY))
@@ -880,30 +885,31 @@ public Completion createLambdaItem(CompilationInfo info, TypeElement elem, Decla
public Completion createRecordPatternItem(CompilationInfo info, TypeElement elem, DeclaredType type, int substitutionOffset, ReferencesCount referencesCount, boolean isDeprecated, boolean insideNew, boolean addTypeVars) {
String simpleName = elem.getSimpleName().toString();
Iterator extends RecordComponentElement> it = elem.getRecordComponents().iterator();
- StringBuilder label = new StringBuilder(elem.getSimpleName());
- StringBuilder insertText = new StringBuilder(elem.getSimpleName());
+ StringBuilder labelDetail = new StringBuilder();
+ StringBuilder insertText = new StringBuilder(simpleName);
RecordComponentElement recordComponent;
int cnt = 1;
- label.append("(");
+ labelDetail.append("(");
insertText.append("(");
while (it.hasNext()) {
recordComponent = it.next();
CharSequence typeName = Utilities.getTypeName(info, recordComponent.getAccessor().getReturnType(), false);
- label.append(typeName);
+ labelDetail.append(typeName);
insertText.append("${").append(cnt++).append(":").append(typeName).append("}");
- label.append(" ");
+ labelDetail.append(" ");
insertText.append(" ");
- label.append(recordComponent.getSimpleName());
+ labelDetail.append(recordComponent.getSimpleName());
insertText.append("${").append(cnt++).append(":").append(recordComponent.getSimpleName()).append("}");
if (it.hasNext()) {
- label.append(", ");
+ labelDetail.append(", ");
insertText.append(", ");
}
}
- label.append(")");
+ labelDetail.append(")");
insertText.append(")");
- return CompletionCollector.newBuilder(label.toString())
+ return CompletionCollector.newBuilder(simpleName)
.kind(Completion.Kind.Struct)
+ .labelDetail(labelDetail.toString())
.insertText(insertText.toString())
.insertTextFormat(Completion.TextFormat.Snippet)
.sortText(String.format("%04d%s#", 650, simpleName))
@@ -922,9 +928,6 @@ private Completion createTypeItem(CompilationInfo info, String prefix, ElementHa
insertText.append(prefix);
}
label.append(elem.getSimpleName());
- if (pkgName.length() > 0) {
- label.append(" (").append(pkgName).append(')');
- }
boolean asTemplate = false;
boolean inImport = false;
int cnt = 1;
@@ -1003,6 +1006,9 @@ private Completion createTypeItem(CompilationInfo info, String prefix, ElementHa
builder.insertTextFormat(Completion.TextFormat.Snippet)
.addCommitCharacter('.');
}
+ if (pkgName.length() > 0) {
+ builder.labelDescription(pkgName);
+ }
if (insideNew) {
builder.command(new Command("Invoke Completion", "editor.action.triggerSuggest"));
}
@@ -1022,11 +1028,11 @@ private Completion createExecutableItem(CompilationInfo info, ExecutableElement
String simpleName = name != null ? name : (elem.getKind() == ElementKind.METHOD ? elem : elem.getEnclosingElement()).getSimpleName().toString();
Iterator extends VariableElement> it = elem.getParameters().iterator();
Iterator extends TypeMirror> tIt = type.getParameterTypes().iterator();
- StringBuilder label = new StringBuilder();
+ StringBuilder labelDetail = new StringBuilder();
StringBuilder insertText = new StringBuilder();
StringBuilder sortParams = new StringBuilder();
- label.append(simpleName).append("(");
insertText.append(simpleName);
+ labelDetail.append("(");
if (!inImport && !memberRef) {
insertText.append(CodeStyle.getDefault(doc).spaceBeforeMethodCallParen() ? " (" : "(");
}
@@ -1042,7 +1048,7 @@ private Completion createExecutableItem(CompilationInfo info, ExecutableElement
cnt++;
String paramTypeName = Utilities.getTypeName(info, tm, false, elem.isVarArgs() && !tIt.hasNext()).toString();
String paramName = it.next().getSimpleName().toString();
- label.append(paramTypeName).append(' ').append(paramName);
+ labelDetail.append(paramTypeName).append(' ').append(paramName);
sortParams.append(paramTypeName);
if (!inImport && !memberRef) {
VariableElement inst = instanceOf(tm, paramName);
@@ -1050,7 +1056,7 @@ private Completion createExecutableItem(CompilationInfo info, ExecutableElement
asTemplate = true;
}
if (tIt.hasNext()) {
- label.append(", ");
+ labelDetail.append(", ");
sortParams.append(',');
if (!inImport && !memberRef) {
insertText.append(", ");
@@ -1058,11 +1064,8 @@ private Completion createExecutableItem(CompilationInfo info, ExecutableElement
}
}
sortParams.append(')');
- label.append(')');
+ labelDetail.append(')');
TypeMirror retType = type.getReturnType();
- if (elem.getKind() == ElementKind.METHOD) {
- label.append(" : ").append(Utilities.getTypeName(info, retType, false).toString());
- }
if (inImport) {
insertText.append(';');
} else if (!memberRef) {
@@ -1089,10 +1092,14 @@ private Completion createExecutableItem(CompilationInfo info, ExecutableElement
}
}
int priority = elem.getKind() == ElementKind.METHOD ? smartType ? 500 : 1500 : smartType ? 650 : name != null ? 1550 : 1650;
- CompletionCollector.Builder builder = CompletionCollector.newBuilder(label.toString())
+ CompletionCollector.Builder builder = CompletionCollector.newBuilder(simpleName)
.kind(elementKind2CompletionItemKind(elem.getKind()))
+ .labelDetail(labelDetail.toString())
.insertTextFormat(asTemplate ? Completion.TextFormat.Snippet : Completion.TextFormat.PlainText)
.sortText(String.format("%04d%s#%02d%s", priority, simpleName, cnt, sortParams.toString()));
+ if (elem.getKind() == ElementKind.METHOD) {
+ builder.labelDescription(Utilities.getTypeName(info, retType, false).toString());
+ }
TextEdit textEdit = null;
String filter = null;
if (castType != null) {
diff --git a/java/java.lsp.server/nbproject/project.xml b/java/java.lsp.server/nbproject/project.xml
index 2994df98cff1..3fb4b6839b1b 100644
--- a/java/java.lsp.server/nbproject/project.xml
+++ b/java/java.lsp.server/nbproject/project.xml
@@ -136,7 +136,7 @@
1
- 1.23
+ 1.24
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
index 4a101d81ce05..75da7c24a69e 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
@@ -94,6 +94,7 @@
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.lsp4j.CompletionItemLabelDetails;
import org.eclipse.lsp4j.CompletionItemTag;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionParams;
@@ -372,6 +373,12 @@ public CompletableFuture, CompletionList>> completio
prefs.put("classMemberInsertionPoint", CodeStyle.InsertionPoint.CARET_LOCATION.name());
boolean isComplete = Completion.collect(doc, caret, context, completion -> {
CompletionItem item = new CompletionItem(completion.getLabel());
+ if (completion.getLabelDetail() != null || completion.getLabelDescription() != null) {
+ CompletionItemLabelDetails labelDetails = new CompletionItemLabelDetails();
+ labelDetails.setDetail(completion.getLabelDetail());
+ labelDetails.setDescription(completion.getLabelDescription());
+ item.setLabelDetails(labelDetails);
+ }
if (completion.getKind() != null) {
item.setKind(CompletionItemKind.valueOf(completion.getKind().name()));
}
diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
index a1e6d53ab386..b741fcb49358 100644
--- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
+++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
@@ -59,6 +59,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.stream.Collectors;
import javax.lang.model.element.ElementKind;
import javax.swing.Icon;
@@ -78,6 +79,7 @@
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.lsp4j.CompletionItemLabelDetails;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionParams;
import org.eclipse.lsp4j.ConfigurationParams;
@@ -223,6 +225,20 @@ public class ServerTest extends NbTestCase {
private final Gson gson = new Gson();
private Socket client;
private Thread serverThread;
+ private Function completionItemToString = ci -> {
+ StringBuilder sb = new StringBuilder();
+ sb.append(ci.getKind()).append(':').append(ci.getLabel());
+ if (ci.getLabelDetails() != null) {
+ CompletionItemLabelDetails labelDetails = ci.getLabelDetails();
+ if (labelDetails.getDetail() != null) {
+ sb.append(labelDetails.getDetail());
+ }
+ if (labelDetails.getDescription() != null) {
+ sb.append(" : ").append(labelDetails.getDescription());
+ }
+ }
+ return sb.toString();
+ };
public ServerTest(String name) {
super(name);
@@ -385,7 +401,7 @@ public void testMain() throws Exception {
int hashCodeStart = code.indexOf("hashCode");
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, hashCodeStart + 2))).get();
assertTrue(completion.isRight());
- List actualItems = completion.getRight().getItems().stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
+ List actualItems = completion.getRight().getItems().stream().map(completionItemToString).collect(Collectors.toList());
assertEquals(Arrays.asList("Method:hashCode() : int"), actualItems);
VersionedTextDocumentIdentifier id = new VersionedTextDocumentIdentifier(1);
id.setUri(toURI(src));
@@ -393,14 +409,14 @@ public void testMain() throws Exception {
assertDiags(diags, "Error:0:38-0:41");//errors
assertDiags(diags, "Error:0:38-0:41");//hints
completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, hashCodeStart + 2))).get();
- actualItems = completion.getRight().getItems().stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
+ actualItems = completion.getRight().getItems().stream().map(completionItemToString).collect(Collectors.toList());
if (jdk9Plus()) {
assertEquals(Arrays.asList("Method:equals(Object anObject) : boolean", "Method:equalsIgnoreCase(String anotherString) : boolean"), actualItems);
}
int testStart = code.indexOf("test") + "equ".length() - "hashCode".length();
completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, testStart + 3))).get();
List actualCompletionItem = completion.getRight().getItems();
- actualItems = actualCompletionItem.stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
+ actualItems = actualCompletionItem.stream().map(completionItemToString).collect(Collectors.toList());
assertEquals(Arrays.asList("Method:test() : void"), actualItems);
assertEquals(null, actualCompletionItem.get(0).getDocumentation());
CompletionItem resolvedItem = server.getTextDocumentService().resolveCompletionItem(actualCompletionItem.get(0)).get();
@@ -414,7 +430,7 @@ public void testMain() throws Exception {
"\n",
resolvedItem.getDocumentation().getRight().getValue());
completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, 0))).get();
- actualItems = completion.getRight().getItems().stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
+ actualItems = completion.getRight().getItems().stream().map(completionItemToString).collect(Collectors.toList());
assertTrue(actualItems.contains("Keyword:interface"));
server.getTextDocumentService().didChange(new DidChangeTextDocumentParams(id, Arrays.asList(new TextDocumentContentChangeEvent(new Range(new Position(0, hashCodeStart), new Position(0, hashCodeStart + "equ".length())), "equ".length(), "hashCode"))));
int closingBrace = code.lastIndexOf("}");
@@ -1516,11 +1532,11 @@ public void logMessage(MessageParams arg0) {
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(2, 8 + "s.".length()))).get();
assertTrue(completion.isRight());
- Optional lengthItem = completion.getRight().getItems().stream().filter(ci -> "length() : int".equals(ci.getLabel())).findAny();
+ Optional lengthItem = completion.getRight().getItems().stream().filter(ci -> "length".equals(ci.getLabel())).findAny();
assertTrue("Expecting length field: " + completion.getRight().getItems(), lengthItem.isPresent());
assertEquals(InsertTextFormat.PlainText, lengthItem.get().getInsertTextFormat());
assertEquals("length()", lengthItem.get().getInsertText());
- Optional substringItem = completion.getRight().getItems().stream().filter(ci -> ci.getLabel().startsWith("substring(") && ci.getLabel().contains(",")).findAny();
+ Optional substringItem = completion.getRight().getItems().stream().filter(ci -> "substring".equals(ci.getLabel()) && ci.getLabelDetails().getDetail().contains(",")).findAny();
assertTrue(substringItem.isPresent());
assertEquals(InsertTextFormat.Snippet, substringItem.get().getInsertTextFormat());
if ("1.8".equals(javaVersion)) {
@@ -1552,9 +1568,9 @@ public void logMessage(MessageParams arg0) {
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), afterJavaLangAnnotation)).get();
assertTrue(completion.isRight());
completion.getRight().getItems().stream().forEach(ci -> System.err.println(ci.getLabel()));
- Optional targetItem = completion.getRight().getItems().stream().filter(ci -> "Target (java.lang.annotation)".equals(ci.getLabel())).findAny();
+ Optional targetItem = completion.getRight().getItems().stream().filter(ci -> "Target".equals(ci.getLabel())).findAny();
assertTrue(targetItem.isPresent());
- assertEquals("Target (java.lang.annotation)", targetItem.get().getLabel()); //TODO: insert text '('!
+ assertEquals("Target", targetItem.get().getLabel()); //TODO: insert text '('!
assertEquals(CompletionItemKind.Interface, targetItem.get().getKind());
}
@@ -1654,7 +1670,7 @@ public void logMessage(MessageParams arg0) {
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(2, 8 + "ArrayL".length()))).get();
assertTrue(completion.isRight());
- Optional arrayListItem = completion.getRight().getItems().stream().filter(ci -> "ArrayList (java.util)".equals(ci.getLabel())).findAny();
+ Optional arrayListItem = completion.getRight().getItems().stream().filter(ci -> "ArrayList".equals(ci.getLabel())).findAny();
assertTrue(arrayListItem.isPresent());
assertNull(arrayListItem.get().getAdditionalTextEdits());
CompletableFuture resolvedItem = server.getTextDocumentService().resolveCompletionItem(arrayListItem.get());
@@ -1671,7 +1687,7 @@ public void logMessage(MessageParams arg0) {
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(3, 8 + "ArrayL".length()))).get();
assertTrue(completion.isRight());
- Optional arrayListItem = completion.getRight().getItems().stream().filter(ci -> "ArrayList (java.util)".equals(ci.getLabel())).findAny();
+ Optional arrayListItem = completion.getRight().getItems().stream().filter(ci -> "ArrayList".equals(ci.getLabel())).findAny();
assertTrue(arrayListItem.isPresent());
assertNull(arrayListItem.get().getAdditionalTextEdits());
CompletableFuture resolvedItem = server.getTextDocumentService().resolveCompletionItem(arrayListItem.get());
@@ -5016,8 +5032,8 @@ public void testAnnotationCompletion() throws Exception {
server.getTextDocumentService().didOpen(new DidOpenTextDocumentParams(new TextDocumentItem(toURI(src), "java", 0, code)));
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, 15))).get();
assertTrue(completion.isRight());
- List actualItems = completion.getRight().getItems().stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
- assertEquals(Arrays.asList("Interface:SuppressWarnings (java.lang)"), actualItems);
+ List actualItems = completion.getRight().getItems().stream().map(completionItemToString).collect(Collectors.toList());
+ assertEquals(Arrays.asList("Interface:SuppressWarnings : java.lang"), actualItems);
VersionedTextDocumentIdentifier id = new VersionedTextDocumentIdentifier(1);
id.setUri(toURI(src));
server.getTextDocumentService().didChange(new DidChangeTextDocumentParams(id, Arrays.asList(new TextDocumentContentChangeEvent(new Range(new Position(0, 1), new Position(0, 15)), 14, "SuppressWarnings(v"))));
@@ -5662,7 +5678,7 @@ public void testDeclarativeHints() throws Exception {
server.getTextDocumentService().didChange(new DidChangeTextDocumentParams(id, Arrays.asList(new TextDocumentContentChangeEvent(new Range(new Position(0, 11), new Position(0, 11)), 0, " :: $1 instanceof java.lang.String"))));
Either, CompletionList> completion = server.getTextDocumentService().completion(new CompletionParams(new TextDocumentIdentifier(toURI(src)), new Position(0, 5))).get();
assertTrue(completion.isRight());
- List actualItems = completion.getRight().getItems().stream().map(ci -> ci.getKind() + ":" + ci.getLabel()).collect(Collectors.toList());
+ List actualItems = completion.getRight().getItems().stream().map(completionItemToString).collect(Collectors.toList());
assertEquals(Arrays.asList("Method:length() : int"), actualItems);
}