diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SignatureHelpRequestor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SignatureHelpRequestor.java index 48e6448af3..e96c2ef3e7 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SignatureHelpRequestor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/contentassist/SignatureHelpRequestor.java @@ -13,6 +13,7 @@ package org.eclipse.jdt.ls.core.internal.contentassist; +import static org.eclipse.jdt.internal.corext.template.java.SignatureUtil.fix83600; import static org.eclipse.jdt.internal.corext.template.java.SignatureUtil.getLowerBound; import java.io.IOException; @@ -35,6 +36,10 @@ import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal; +import org.eclipse.jdt.internal.codeassist.impl.Engine; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.corext.template.java.SignatureUtil; import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; @@ -176,33 +181,42 @@ public String computeJavaDoc(CompletionProposal proposal) { try { IType type = unit.getJavaProject().findType(SignatureUtil.stripSignatureToFQN(String.valueOf(proposal.getDeclarationSignature()))); if (type != null) { - String[] parameters= Signature.getParameterTypes(String.valueOf(SignatureUtil.fix83600(proposal.getSignature()))); - for (int i= 0; i < parameters.length; i++) { - parameters[i]= getLowerBound(parameters[i]); - } - - IMethod method = JavaModelUtil.findMethod(String.valueOf(proposal.getName()), parameters, proposal.isConstructor(), type); - - if (method != null && method.exists()) { - ICompilationUnit unit = type.getCompilationUnit(); - if (unit != null) { - unit.reconcile(ICompilationUnit.NO_AST, false, null, null); + if (proposal instanceof InternalCompletionProposal) { + Binding binding = ((InternalCompletionProposal) proposal).getBinding(); + if (binding instanceof MethodBinding) { + MethodBinding methodBinding = (MethodBinding) binding; + MethodBinding original = methodBinding.original(); + char[] signature; + if (original != binding) { + signature = Engine.getSignature(original); + } else { + signature = Engine.getSignature(methodBinding); + } + String[] parameters = Signature.getParameterTypes(String.valueOf(fix83600(signature))); + for (int i = 0; i < parameters.length; i++) { + parameters[i] = getLowerBound(parameters[i]); + } + IMethod method = JavaModelUtil.findMethod(String.valueOf(proposal.getName()), parameters, proposal.isConstructor(), type); + if (method != null && method.exists()) { + ICompilationUnit unit = type.getCompilationUnit(); + if (unit != null) { + unit.reconcile(ICompilationUnit.NO_AST, false, null, null); + } + String javadoc = null; + try { + javadoc = SimpleTimeLimiter.create(Executors.newCachedThreadPool()).callWithTimeout(() -> { + Reader reader = JavadocContentAccess.getPlainTextContentReader(method); + return reader == null ? null : CharStreams.toString(reader); + }, 500, TimeUnit.MILLISECONDS); + } catch (UncheckedTimeoutException tooSlow) { + } catch (Exception e) { + JavaLanguageServerPlugin.logException("Unable to read documentation", e); + } + return javadoc; + } } - - String javadoc = null; - try { - javadoc = SimpleTimeLimiter.create(Executors.newCachedThreadPool()).callWithTimeout(() -> { - Reader reader = JavadocContentAccess.getPlainTextContentReader(method); - return reader == null? null:CharStreams.toString(reader); - }, 500, TimeUnit.MILLISECONDS); - } catch (UncheckedTimeoutException tooSlow) { - } catch (Exception e) { - JavaLanguageServerPlugin.logException("Unable to read documentation", e); - } - return javadoc; } } - } catch (JavaModelException e) { JavaLanguageServerPlugin.logException("Unable to resolve signaturehelp javadoc", e); } diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionResolveHandler.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionResolveHandler.java index e8a5a26497..e93fa46019 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionResolveHandler.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionResolveHandler.java @@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IMember; @@ -30,6 +31,10 @@ import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.codeassist.InternalCompletionProposal; +import org.eclipse.jdt.internal.codeassist.impl.Engine; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.ls.core.internal.JDTUtils; import org.eclipse.jdt.ls.core.internal.JSONUtility; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; @@ -105,14 +110,28 @@ public CompletionItem resolve(CompletionItem param, IProgressMonitor monitor) { IType type = unit.getJavaProject().findType(typeName); if (type!=null && data.containsKey(DATA_FIELD_NAME)) { + CompletionProposal proposal = completionResponse.getProposals().get(proposalId); String name = data.get(DATA_FIELD_NAME); String[] paramSigs = CharOperation.NO_STRINGS; if(data.containsKey( DATA_FIELD_SIGNATURE)){ - String[] parameters= Signature.getParameterTypes(String.valueOf(fix83600(data.get(DATA_FIELD_SIGNATURE).toCharArray()))); - for (int i= 0; i < parameters.length; i++) { - parameters[i]= getLowerBound(parameters[i]); + if (proposal instanceof InternalCompletionProposal) { + Binding binding = ((InternalCompletionProposal) proposal).getBinding(); + if (binding instanceof MethodBinding) { + MethodBinding methodBinding = (MethodBinding) binding; + MethodBinding original = methodBinding.original(); + char[] signature; + if (original != binding) { + signature = Engine.getSignature(original); + } else { + signature = Engine.getSignature(methodBinding); + } + String[] parameters = Signature.getParameterTypes(String.valueOf(fix83600(signature))); + for (int i = 0; i < parameters.length; i++) { + parameters[i] = getLowerBound(parameters[i]); + } + paramSigs = parameters; + } } - paramSigs = parameters; } IMethod method = type.getMethod(name, paramSigs); IMethod[] methods = type.findMethods(method); diff --git a/org.eclipse.jdt.ls.tests/projects/eclipse/hello/src/org/sample/MyList.java b/org.eclipse.jdt.ls.tests/projects/eclipse/hello/src/org/sample/MyList.java new file mode 100644 index 0000000000..3fb044c42f --- /dev/null +++ b/org.eclipse.jdt.ls.tests/projects/eclipse/hello/src/org/sample/MyList.java @@ -0,0 +1,13 @@ +package org.sample; + +import java.util.Collection; +import java.util.List; + +public interface MyList extends List { + + /** + * Test + */ + boolean add(E e); + +} diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java index 16e3517597..8bba19dccb 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/CompletionHandlerTest.java @@ -2628,6 +2628,34 @@ public void testCompletion_ConstantDefaultValue() throws JavaModelException { assertEquals("Default: \"test\"", documentation); } + // See https://github.com/redhat-developer/vscode-java/issues/1258 + @Test + public void testCompletion_javadocOriginal() throws JavaModelException { + ICompilationUnit unit = getWorkingCopy("src/org/sample/Test.java", + //@formatter:off + "package org.sample;\n" + + "import java.util.List;\n" + + "import java.util.LinkedList;\n" + + "public class Test {\n\n" + + " void test() {\n" + + " MyList l = new LinkedList<>();\n" + + " l.add\n" + + " }\n" + + "}\n"); + //@formatter:on + int[] loc = findCompletionLocation(unit, "l.add"); + CompletionList list = server.completion(JsonMessageHelper.getParams(createCompletionRequest(unit, loc[0], loc[1]))).join().getRight(); + assertNotNull(list); + assertEquals(4, list.getItems().size()); + CompletionItem ci = list.getItems().get(0); + assertEquals(CompletionItemKind.Method, ci.getKind()); + assertEquals("add(String e) : boolean", ci.getLabel()); + CompletionItem resolvedItem = server.resolveCompletionItem(ci).join(); + assertEquals(CompletionItemKind.Method, resolvedItem.getKind()); + String documentation = resolvedItem.getDocumentation().getLeft(); + assertEquals(" Test ", documentation); + } + private String createCompletionRequest(ICompilationUnit unit, int line, int kar) { return COMPLETION_TEMPLATE.replace("${file}", JDTUtils.toURI(unit)) .replace("${line}", String.valueOf(line))