-
Notifications
You must be signed in to change notification settings - Fork 11
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
Add some clangd LSP extensions to the ClangdLanguageServer API #256
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution @travkin79
Before moving on, the following issues need to be resolved:
- copyright headers should be provided
- commits should be squashed to one
Do you plan to add any test to demonstrate new API in action?
bundles/org.eclipse.cdt.lsp/src/org/eclipse/cdt/lsp/services/ast/AstNode.java
Show resolved
Hide resolved
bundles/org.eclipse.cdt.lsp/src/org/eclipse/cdt/lsp/services/ast/AstParams.java
Show resolved
Hide resolved
bundles/org.eclipse.cdt.lsp/src/org/eclipse/cdt/lsp/services/symbolinfo/RangeAndUri.java
Show resolved
Hide resolved
bundles/org.eclipse.cdt.lsp/src/org/eclipse/cdt/lsp/services/symbolinfo/SymbolDetails.java
Show resolved
Hide resolved
Thanks for your feedback @ruspl-afed,
Done.
I thought of some simple integration tests that use the LS using clangd (call the API and check the return value), but I don't know how to run clangd in a test environment. Maybe its better to use a LS mock, but then, I'm not sure what to test at all. :-) |
* | ||
* @see {@link ClangdLanguageServer#getAst(AstParams)} | ||
*/ | ||
public class AstNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I has a smell that cdt-lsp is providing these classes without using them. That's dead code in an exported package. @travkin79 could implement these classes in your custom plug-in where its used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could implement these classes in your custom plug-in where its used?
Forget my comment, I think it s to be implemented here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These classes are part of the extended ClangdLanguageServer
interface. Without them, the code will not compile and LSP4J will not be able to parse the LS response. Removing these classes would mean to remove the new methods from the ClangdLanguageServer
interface, i.e. removing the new clangd LSP extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks!
Mock would be enough. The idea was to show how to use newly added API, not to test the real clangd response. |
@travkin79 Thank you! |
@travkin79 I was wondering if you have any open source examples of using the clangd extensions in CDT LSP? Or, If you have used it internally, can you share a line or two of how you have used it? I am preparing my talk for EclipseCon next week and I want to highlight this change and how it is used in practice. |
Hi @jonahgraham, I have no open source code that uses the new extensions from clangd, but I can give you some code excerpts using it. I must admit, we use only one of the two new LSP extensions. I tried using the AST extension from LSP4E, CDT LSP, and clangd, but the responses from clangd were not convincing (not enough data or not as expected). Thus, we stopped using the AST API. But we're actively using SymbolInfo API from LSP4E, CDT LSP, and clangd. We use it for retrieving some detailed documentation from an additional (code complementing) documentation model. We take a selected element in a CDT LSP editor, calculate a fully qualified name in order to create a URI, then resolve it in a documentation model and finally display the element's (enriched) documentation in a custom documentation view. I'm not sure what code examples you're interested in, so here are some more lines that show you the new extension's usage: import org.eclipse.xtext.naming.QualifiedName;
// ...
public URI resolveDocumentation(IEditorInput editorInput, ITextSelection selection, IProgressMonitor monitor) {
// ...
if (editorInput instanceof IFileEditorInput) {
IFileEditorInput input = (IFileEditorInput) editorInput;
IDocument document = LSPEclipseUtils.getDocument(input.getFile());
if (document != null) {
// calculate qualified name first and check if we have a documentation
List<SymbolDetails> symbolDetails = requestSymbolInfoFromLS(selection, document);
for (SymbolDetails details: symbolDetails) {
String name = details.getName();
String containerName = details.getContainerName();
String qualifiedName = containerName + name;
String[] qualifiedNameSegments = qualifiedName.split("::");
String memberName = null;
// calculate member name if any
// ...
QualifiedName qualifiedElementName = QualifiedName.create(qualifiedNameSegments);
URI uri = documentationModel.computeElementUri(qualifiedElementName, memberName, progress.split(50));
if (uri != null) {
return uri;
}
}
}
}
// ...
}
private List<SymbolDetails> requestSymbolInfoFromLS(ITextSelection selection, IDocument document) {
try {
TextDocumentPositionParams params = LSPEclipseUtils.toTextDocumentPosistionParams(
selection.getOffset(), document);
return requestSymbolInfoFromLS(params, document);
} catch (BadLocationException e) {
//...log(e);
}
return Collections.emptyList();
}
private List<SymbolDetails> requestSymbolInfoFromLS(TextDocumentPositionParams params, IDocument document) {
try {
Optional<SymbolDetails[]> response = LanguageServers.forDocument(document)
.computeFirst(server -> {
if (server instanceof ClangdLanguageServer) {
return ((ClangdLanguageServer) server).getSymbolInfo(params);
}
return null;
}).get();
if (response.isPresent()) {
return Arrays.asList(response.get()).stream()
.filter(detail -> detail != null)
.collect(Collectors.toList());
}
} catch (ExecutionException e) {
// ...log(e);
} catch (InterruptedException e) {
Thread.interrupted();
// ...log(e);
}
return Collections.emptyList();
} Concerning CDT LSP challenges, there are a few, I'm interested in. You might consider the following GitHub issues / PRs / discussions interesting or noteworthy:
|
Thanks @travkin79 this is very useful and I will incorporate this into my talk. I will probably publish my talk slides on https://kichwacoders.com/blog/ after EclipseCon. I also expect the EF to publish the talks on Youtube in a EclipseCon 2024 playlist https://www.youtube.com/@EclipseFdn/playlists |
See discussion #253