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

feat: Support for TypeHierachy + CallHierarchy #612

Merged
merged 1 commit into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 66 additions & 10 deletions docs/LSPSupport.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ Current state of [Language Features]( https://microsoft.github.io/language-serve
* ✅ [textDocument/typeDefinition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_typeDefinition) (see [implementation details](#type-definition))
* ✅ [textDocument/implementation](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_implementation) (see [implementation details](#implementation))
* ✅ [textDocument/references](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references) (see [implementation details](#references))
* ❌ [textDocument/prepareCallHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareCallHierarchy).
* ❌ [textDocument/incomingCalls](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#callHierarchy_incomingCalls).
* ❌ [textDocument/outgoingCalls](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#callHierarchy_outgoingCalls).
* ❌ [textDocument/prepareTypeHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareTypeHierarchy).
* ❌ [typeHierarchy/supertypes](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#typeHierarchy_supertypes).
* ✅ [textDocument/prepareCallHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareCallHierarchy) (see [implementation details](#call-hierarchy))
* ✅ [textDocument/incomingCalls](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#callHierarchy_incomingCalls).
* ✅ [textDocument/outgoingCalls](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#callHierarchy_outgoingCalls).
* ✅ [textDocument/prepareTypeHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareTypeHierarchy) (see [implementation details](#type-hierarchy))
* ✅ [typeHierarchy/subtypes](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#typeHierarchy_subtypes).
* ✅ [typeHierarchy/supertypes](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#typeHierarchy_supertypes).
* ✅ [textDocument/foldingRange](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_foldingRange) (see [implementation details](#folding-range))
* ❌ [textDocument/selectionRange](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_selectionRange).
* ✅ [textDocument/documentSymbol](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentSymbol) (see [implementation details](#document-symbol))
Expand Down Expand Up @@ -129,7 +130,7 @@ This menu action either opens the reference in a popup or navigates to the refer

![textDocument/implementation popup](./images/lsp-support/textDocument_references_popup.png)

[textDocument/references](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references) is used too via [Find Usages](./UserGuide.md#find-usages) to show references.
[textDocument/references](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references) is used also via [Find Usages](./UserGuide.md#find-usages) to show references.

### Implementation

Expand All @@ -144,7 +145,7 @@ This menu action either opens the implementation in a popup or navigates to the

![textDocument/implementation popup](./images/lsp-support/textDocument_implementation_popup.png)

[textDocument/implementation](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_implementation) is too used via [Find Usages](./UserGuide.md#find-usages) to show implementations.
[textDocument/implementation](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_implementation) is also used via [Find Usages](./UserGuide.md#find-usages) to show implementations.

### Type definition

Expand All @@ -155,7 +156,7 @@ The [textDocument/typeDefinition](https://microsoft.github.io/language-server-pr

This menu action either opens the type definition in a popup or navigates to the type definition if there are several type definitions:

[textDocument/typeDefinition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_typeDefinition) is used too via [Find Usages](./UserGuide.md#find-usages) to show Type definitions.
[textDocument/typeDefinition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_typeDefinition) is also used via [Find Usages](./UserGuide.md#find-usages) to show Type definitions.

### Declaration

Expand All @@ -166,7 +167,7 @@ The [textDocument/declaration](https://microsoft.github.io/language-server-proto

This menu action either opens the declaration in a popup or navigates to the declaration if there are several declarations:

[textDocument/declaration](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_declaration) is used too via [Find Usages](./UserGuide.md#find-usages) to show declarations.
[textDocument/declaration](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_declaration) is also used via [Find Usages](./UserGuide.md#find-usages) to show declarations.

### Document Highlight

Expand Down Expand Up @@ -561,9 +562,64 @@ Here is an example with [TypeScript Language Server](./user-defined-ls/typescrip
which opens the standard `File Structure` with `Ctrl+F12` / `Cmd+F12`
(also available with the `Navigate / File Structure` menu) to display TypeScript functions as symbols and navigate them easily:

You can also open the `Structure` view using the `View / Tool Windows / Structure` menu:

![textDocument/documentSymbol](./images/lsp-support/textDocument_documentSymbol.gif)

You can too open the `Structure` view with `View / Tool Windows / Structure` menu:
### Call Hierarchy

[textDocument/prepareCallHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareCallHierarchy) is implemented with
the `callHierarchyProvider` extension point. By default, LSP4IJ registers the `callHierarchyProvider` with
[LSPCallHierarchyProvider](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/features/callHierarchy/LSPCallHierarchyProvider.java) class for `TEXT` and `textmate` languages:

```xml
<!-- LSP textDocument/callHierarchy request support -->
<callHierarchyProvider
language="TEXT"
implementationClass="com.redhat.devtools.lsp4ij.features.callHierarchy.LSPCallHierarchyProvider" />
<callHierarchyProvider
language="textmate"
implementationClass="com.redhat.devtools.lsp4ij.features.callHierarchy.LSPCallHierarchyProvider" />
```

If you use another language, you will have to declare `callHierarchyProvider` with your language:

```xml
<callHierarchyProvider
language="YourLanguage"
implementationClass="com.redhat.devtools.lsp4ij.features.callHierarchy.LSPCallHierarchyProvider" />
```

After setting the cursor position in a file, you can view the Call Hierarchy using the `Navigate / Call Hierarchy` menu (or `Ctrl+Alt+H`).
Below is an example of a call hierarchy using the [Go Language Server](./user-defined-ls/gopls.md):

![textDocument/callHierarchy](./images/lsp-support/textDocument_callHierarchy.png)

### Type Hierarchy

[textDocument/prepareTypeHierarchy](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_prepareTypeHierarchy) is implemented with
the `typeHierarchyProvider` extension point. By default, LSP4IJ registers the `typeHierarchyProvider` with
[LSPTypeHierarchyProvider](https://github.com/redhat-developer/lsp4ij/blob/main/src/main/java/com/redhat/devtools/lsp4ij/features/typeHierarchy/LSPTypeHierarchyProvider.java) class for `TEXT` and `textmate` languages:

```xml
<!-- LSP textDocument/typeHierarchy request support -->
<typeHierarchyProvider
language="TEXT"
implementationClass="com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPTypeHierarchyProvider" />
<typeHierarchyProvider
language="textmate"
implementationClass="com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPTypeHierarchyProvider" />
```

If you use another language, you will have to declare `typeHierarchyProvider` with your language:

```xml
<typeHierarchyProvider
language="YourLanguage"
implementationClass="com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPTypeHierarchyProvider" />
```

After setting the cursor position in a file, you can view the Type Hierarchy using the `Navigate / Type Hierarchy` menu (or `Ctrl+H`).

### Workspace Symbol

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.features.callHierarchy.LSPCallHierarchyIncomingCallsSupport;
import com.redhat.devtools.lsp4ij.features.callHierarchy.LSPCallHierarchyOutgoingCallsSupport;
import com.redhat.devtools.lsp4ij.features.callHierarchy.LSPPrepareCallHierarchySupport;
import com.redhat.devtools.lsp4ij.features.codeAction.intention.LSPIntentionCodeActionSupport;
import com.redhat.devtools.lsp4ij.features.codeLens.LSPCodeLensSupport;
import com.redhat.devtools.lsp4ij.features.color.LSPColorSupport;
Expand All @@ -34,6 +37,9 @@
import com.redhat.devtools.lsp4ij.features.semanticTokens.LSPSemanticTokensSupport;
import com.redhat.devtools.lsp4ij.features.signatureHelp.LSPSignatureHelpSupport;
import com.redhat.devtools.lsp4ij.features.typeDefinition.LSPTypeDefinitionSupport;
import com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPPrepareTypeHierarchySupport;
import com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPTypeHierarchySubtypesSupport;
import com.redhat.devtools.lsp4ij.features.typeHierarchy.LSPTypeHierarchySupertypesSupport;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -87,6 +93,14 @@ public class LSPFileSupport extends UserDataHolderBase implements Disposable {

private final LSPDocumentSymbolSupport documentSymbolSupport;

private final LSPPrepareCallHierarchySupport prepareCallHierarchySupport;
private final LSPCallHierarchyIncomingCallsSupport callHierarchyIncomingCallsSupport;
private final LSPCallHierarchyOutgoingCallsSupport callHierarchyOutgoingCallsSupport;

private final LSPPrepareTypeHierarchySupport prepareTypeHierarchySupport;
private final LSPTypeHierarchySubtypesSupport typeHierarchySubtypesSupport;
private final LSPTypeHierarchySupertypesSupport typeHierarchySupertypesSupport;

private LSPFileSupport(@NotNull PsiFile file) {
this.file = file;
this.codeLensSupport = new LSPCodeLensSupport(file);
Expand All @@ -109,6 +123,12 @@ private LSPFileSupport(@NotNull PsiFile file) {
this.typeDefinitionSupport = new LSPTypeDefinitionSupport(file);
this.semanticTokensSupport = new LSPSemanticTokensSupport(file);
this.documentSymbolSupport = new LSPDocumentSymbolSupport(file);
this.prepareCallHierarchySupport = new LSPPrepareCallHierarchySupport(file);
this.callHierarchyIncomingCallsSupport = new LSPCallHierarchyIncomingCallsSupport(file);
this.callHierarchyOutgoingCallsSupport = new LSPCallHierarchyOutgoingCallsSupport(file);
this.prepareTypeHierarchySupport = new LSPPrepareTypeHierarchySupport(file);
this.typeHierarchySubtypesSupport = new LSPTypeHierarchySubtypesSupport(file);
this.typeHierarchySupertypesSupport = new LSPTypeHierarchySupertypesSupport(file);
file.putUserData(LSP_FILE_SUPPORT_KEY, this);
}

Expand All @@ -135,6 +155,12 @@ public void dispose() {
getTypeDefinitionSupport().cancel();
getSemanticTokensSupport().cancel();
getDocumentSymbolSupport().cancel();
getPrepareCallHierarchySupport().cancel();
getCallHierarchyIncomingCallsSupport().cancel();
getCallHierarchyOutgoingCallsSupport().cancel();
getPrepareTypeHierarchySupport().cancel();
getTypeHierarchySubtypesSupport().cancel();
getTypeHierarchySupertypesSupport().cancel();
var map = getUserMap();
for (var key : map.getKeys()) {
var value = map.get(key);
Expand Down Expand Up @@ -324,6 +350,60 @@ public LSPDocumentSymbolSupport getDocumentSymbolSupport() {
return documentSymbolSupport;
}

/**
* Returns the LSP prepare call hierarchy support.
*
* @return the LSP prepare call hierarchy support.
*/
public LSPPrepareCallHierarchySupport getPrepareCallHierarchySupport() {
return prepareCallHierarchySupport;
}

/**
* Returns the LSP call hierarchy incoming calls support.
*
* @return the LSP call hierarchy incoming calls support.
*/
public LSPCallHierarchyIncomingCallsSupport getCallHierarchyIncomingCallsSupport() {
return callHierarchyIncomingCallsSupport;
}

/**
* Returns the LSP prepare call hierarchy outgoing calls support.
*
* @return the LSP prepare call hierarchy outgoing calls support.
*/
public LSPCallHierarchyOutgoingCallsSupport getCallHierarchyOutgoingCallsSupport() {
return callHierarchyOutgoingCallsSupport;
}

/**
* Returns the LSP prepare type hierarchy support.
*
* @return the LSP prepare type hierarchy support.
*/
public LSPPrepareTypeHierarchySupport getPrepareTypeHierarchySupport() {
return prepareTypeHierarchySupport;
}

/**
* Returns the LSP type hierarchy subtypes support.
*
* @return the LSP type hierarchy subtypes support.
*/
public LSPTypeHierarchySubtypesSupport getTypeHierarchySubtypesSupport() {
return typeHierarchySubtypesSupport;
}

/**
* Returns the LSP type hierarchy supertypes support.
*
* @return the LSP type hierarchy supertypes support.
*/
public LSPTypeHierarchySupertypesSupport getTypeHierarchySupertypesSupport() {
return typeHierarchySupertypesSupport;
}

/**
* Return the existing LSP file support for the given Psi file, or create a new one if necessary.
*
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/com/redhat/devtools/lsp4ij/LSPRequestConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class LSPRequestConstants {
public static final String WORKSPACE_WILL_CREATE_FILES = "workspace/willCreateFiles";
public static final String WORKSPACE_WILL_DELETE_FILES = "workspace/willDeleteFiles";
public static final String WORKSPACE_WILL_RENAME_FILES = "workspace/willRenameFiles";
public static final String WORKSPACE_SYMBOL = "workspace/symbol";

// textDocument/* LSP requests

Expand All @@ -31,10 +32,10 @@ public class LSPRequestConstants {
public static final String TEXT_DOCUMENT_TYPE_DEFINITION = "textDocument/typeDefinition";
public static final String TEXT_DOCUMENT_CODE_ACTION = "textDocument/codeAction";
public static final String TEXT_DOCUMENT_CODE_LENS = "textDocument/codeLens";
public static final String TEXT_DOCUMENT_RESOLVE_CODE_LENS = "textDocument/resolveCodelens";
public static final String CODE_LENS_RESOLVE = "codelens/resolve";
public static final String TEXT_DOCUMENT_HOVER = "textDocument/hover";
public static final String TEXT_DOCUMENT_INLAY_HINT = "textDocument/inlayHint";
public static final String TEXT_DOCUMENT_RESOLVE_INLAY_HINT = "textDocument/resolveInlayHint";
public static final String INLAY_HINT_RESOLVE = "inlayHint/resolve";
public static final String TEXT_DOCUMENT_DOCUMENT_COLOR = "textDocument/documentColor";
public static final String TEXT_DOCUMENT_COMPLETION = "textDocument/completion";
public static final String TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT = "textDocument/documentHighlight";
Expand All @@ -45,11 +46,15 @@ public class LSPRequestConstants {
public static final String TEXT_DOCUMENT_SIGNATURE_HELP = "textDocument/signatureHelp";
public static final String TEXT_DOCUMENT_PREPARE_RENAME = "textDocument/prepareRename";
public static final String TEXT_DOCUMENT_RENAME = "textDocument/rename";
public static final String TEXT_DOCUMENT_DOCUMENT_COMPLETION = "textDocument/completion";
public static final String TEXT_DOCUMENT_DOCUMENT_SYMBOL = "textDocument/documentSymbol";

// workspace/* LSP requests
public static final String WORKSPACE_SYMBOL = "workspace/symbol";
public static final String TEXT_DOCUMENT_CALL_HIERARCHY = "textDocument/callHierarchy";
public static final String TEXT_DOCUMENT_PREPARE_CALL_HIERARCHY = "textDocument/prepareCallHierarchy";
public static final String CALL_HIERARCHY_INCOMING_CALLS = "callHierarchy/incomingCalls";
public static final String CALL_HIERARCHY_OUTGOING_CALLS = "callHierarchy/outgoingCalls";
public static final String TEXT_DOCUMENT_PREPARE_TYPE_HIERARCHY = "textDocument/prepareTypeHierarchy";
public static final String TYPE_HIERARCHY_SUB_TYPES = "typeHierarchy/subtypes";
public static final String TYPE_HIERARCHY_SUPER_TYPES = "typeHierarchy/supertypes";
public static final String TEXT_DOCUMENT_TYPE_HIERARCHY = "textDocument/typeHierarchy";

private LSPRequestConstants() {

Expand Down
Loading
Loading