Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completing /** should generate Javadoc with params #744

Merged
merged 1 commit into from
Aug 21, 2018

Conversation

snjeza
Copy link
Contributor

@snjeza snjeza commented Aug 3, 2018

Fixes redhat-developer/vscode-java#228

Signed-off-by: Snjezana Peco [email protected]

@snjeza snjeza requested review from gorkem and fbricon August 3, 2018 21:06
@fbricon
Copy link
Contributor

fbricon commented Aug 7, 2018

@snjeza I haven't checked yet but is there a way for the server, through LSP config/requests to perform what the client does in https://github.com/redhat-developer/vscode-java/blob/1f6783957c699e261a33d05702f2da356017458d/src/extension.ts#L263-L303?

Because your solution is to generate code completion items, which gives a different UX than the expected autocompletion

@snjeza
Copy link
Contributor Author

snjeza commented Aug 7, 2018

The feature I have created works in a similar way as the VS Code typescript feature does.
See https://github.com/Microsoft/vscode/blob/master/extensions/typescript-language-features/src/features/jsDocCompletions.ts
I think we can't implement this feature on the VS Code client side because the client doesn't know arguments of Java methods.

@fbricon
Copy link
Contributor

fbricon commented Aug 7, 2018

Of course it can't be implemented on the client side, I just wondered whether we could move that part (API implementation) currently on the client side to be processed in the backend.

// ignore
}
final CompletionItem ci = new CompletionItem();
ci.setInsertText(buf.toString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insertText is deprecated, you should use a TextEdit.

Also, according to the spec, for completionItem textEdits:

The range of the edit must be a single line range and it must contain the position at which completion has been requested

That means each extra line must be added by an additional textedit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the range must be a single line range.

import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;

public class JavaDocCompletionProposal {
Copy link
Contributor

@fbricon fbricon Aug 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How hard is it to refactor JavaDocAutoIndentStrategy in jdt.ui down to jdt.core?
cc @rgrunber @jjohnstn

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few eclipse.jface.text interfaces that would need to move to eclipse.text. There is a reference to StubUtility and CodeGeneration which is still in the works by Roland. There are two methods (isSmartMode() and getCompilationUnit()) that drag in all the eclipse.ui stuff such as PlatformUI and IEditorPart. The class could be split into core and non-core and the smartMode setting plus ICompilationUnit could be set for core so as to avoid eclipse.ui. There are also a few Preferences to reference/set like we have done before (e.g. Member sort order).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of changes due to which, I think, we won't be able to use the same code in jdt.ls and jdt.ui

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jjohnstn thanks for looking into it. Given the amount of changes and @snjeza's feedback, I'm fine keeping a customized version of that JavaDocAutoIndentStrategy in jdt.ls.

@@ -319,6 +320,30 @@ public void testCompletion_import_package() throws JavaModelException{
//Not checking the range end character
}

@Test
public void testCompletion_javadocComment() throws JavaModelException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add some more tests for:

  • already existing javadoc
  • partially existing javadoc (has only 1 @param doc'ed)
  • no completion after regular comment /* */
  • no completion for no-param methods

ci.setSortText(SortTextHelper.convertRelevance(0));
ci.setKind(CompletionItemKind.Snippet);
ci.setInsertTextFormat(InsertTextFormat.Snippet);
ci.setDocumentation(ci.getInsertText());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example documentation returned: "documentation": " \n * @param foo\n * @param bar\n"
Leading empty lines should be trimmed from documentation

@@ -0,0 +1,235 @@
/*******************************************************************************
* Copyright (c) 2016-2017 Red Hat Inc. and others.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original copyright should be retained

* Based on org.eclipse.jdt.internal.ui.text.javadoc.JavaDocAutoIndentStrategy
*
* Contributors:
* IBM Corporation - initial API and implementation

This comment was marked as resolved.

}
List<CompletionItem> result = new ArrayList<>();
IDocument d = JsonRpcHelpers.toDocument(cu.getBuffer());
if (offset == -1 || d.getLength() == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offset < 0

@fbricon
Copy link
Contributor

fbricon commented Aug 8, 2018

Indentation looks weird
screen shot 2018-08-08 at 4 02 20 pm
In the generated javadoc, I don't see why we're adding trailing spaces on the 1st line:

    /**     
     * @param toto
     * @param tatata
     */
    @Deprecated
    public void name(String toto, String tatata) {

    }

edit:

"newText": "    \n * @param toto\n * @param tatata"

ci.setSortText(SortTextHelper.convertRelevance(0));
ci.setKind(CompletionItemKind.Snippet);
ci.setInsertTextFormat(InsertTextFormat.Snippet);
String documentation = buf.toString().replaceFirst("\\n", "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this leads to an ugly indentation. 1st empty lines should be removed

@fbricon
Copy link
Contributor

fbricon commented Aug 8, 2018

All lines should be trimmed on the right.

ci.setLabel(JAVA_DOC_COMMENT);
ci.setSortText(SortTextHelper.convertRelevance(0));
ci.setKind(CompletionItemKind.Snippet);
ci.setInsertTextFormat(InsertTextFormat.Snippet);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CompletionItemKind.Snippet is fine, but I don't think InsertTextFormat.Snippet is appropriate here, since there will be no placeholders. Clients not supporting Snippets might puke when receiving those items. We should send InsertTextFormat.PlainText

}
final CompletionItem ci = new CompletionItem();
Range range = JDTUtils.toRange(unit, offset, 0);
ci.setTextEdit(new TextEdit(range, buf.toString()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

textedit should also get the rtrim treatment here.

buf.append(rtrim(line));
buf.append(lineDelimiter);
}
return buf.toString().replaceFirst(lineDelimiter, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only if lineDelimiter position is 0

assertEquals(CompletionItemKind.Snippet, item.getKind());
assertEquals("999999999", item.getSortText());
assertNotNull(item.getTextEdit());
assertEquals(" \n * @param i\n * @param s\n", item.getTextEdit().getNewText());
Copy link
Contributor

@fbricon fbricon Aug 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new text should be "\n * @param i\n * @param s\n" (no leading spaces)

@snjeza snjeza force-pushed the issue-228 branch 2 times, most recently from a2d9b34 to 4ac94d1 Compare August 9, 2018 00:18

public class JavaDocCompletionProposal {

public static final String JAVA_DOC_COMMENT = "JavaDoc comment";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/JavaDoc/Javadoc/g

no camelcase in Javadoc

return result;
}

private String rtrim(String text) {
Copy link
Contributor

@fbricon fbricon Aug 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is implemented is a ltrim, i.e. whitespaces on the left are removed. We want to remove the trailing spaces, those on the right

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StringUtils.stripEnd(text, null) should work

@snjeza snjeza force-pushed the issue-228 branch 2 times, most recently from cd62ae9 to 50807c7 Compare August 9, 2018 23:09
@fbricon
Copy link
Contributor

fbricon commented Aug 9, 2018

Trimming is much better BUT I think it now introduces an extra line separator, when completing an existing javadoc block (I think this was not happening in the previous commits)
aug-09-2018 19-44-25

When completing from the initial opening block, there's no gap in the * delimiters
aug-09-2018 19-47-55

@snjeza snjeza force-pushed the issue-228 branch 3 times, most recently from 03e485f to 0177969 Compare August 13, 2018 22:47
@fbricon
Copy link
Contributor

fbricon commented Aug 20, 2018

So the new implementation now adds an extra empty comment line before the parameters :-/
Which made me realize, we could, if the client support snippets, add a $0 placeholder on that 1st empty line, so the user would be able to write javadoc directly after inserting the template.

But if no snippet is supported, then we shouldn't add that extra 1st empty line

@snjeza
Copy link
Contributor Author

snjeza commented Aug 21, 2018

test this please

@snjeza
Copy link
Contributor Author

snjeza commented Aug 21, 2018

@fbricon I have updated the PR.

@fbricon
Copy link
Contributor

fbricon commented Aug 21, 2018

Works really nicely now! Nice job @snjeza

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants