Skip to content

Move Type Hierarchy implementation to LSP - #2376

Closed
CsCherrYY wants to merge 3 commits into
redhat-developer:mainfrom
CsCherrYY:cs-typehierarchy-impl
Closed

CsCherrYY wants to merge 3 commits into
redhat-developer:mainfrom
CsCherrYY:cs-typehierarchy-impl

Conversation

@CsCherrYY

@CsCherrYY CsCherrYY commented Mar 24, 2022 •

Copy link
Copy Markdown
Contributor

Requires eclipse-jdtls/eclipse.jdt.ls#2033

The change is able to review/merge, but we will get several BREAKING changes, so feel free to discuss we can now continue the process or wait for further changes.

Pros:

  • supertype/subtype hierarchy view is supported in vscode, we can get dismiss/history features for free.
  • All communications about TypeHierarchy are based on LSP, as for future updates, we can git it for free.

Cons:

  • The type hierarchy in LSP only supports supertype hierarchy and subtype hierarchy, no class hierarchy. We should still hold custom implementations about the class hierarchy view.

  • Since "Show Type Hierarchy" is contributed from language client/vscode itself, we have no way to control its behavior, so the default view of "Show Type Hierarchy" would be the subtype hierarchy view. We added a new entry "Show Class hierarchy" to open the class hierarchy view by default.
    image

  • As for those types have no children, the star will always show there. This is also the limitation of current call hierarchy view.
    image

@rgrunber

Copy link
Copy Markdown
Member

Can this along with the change on the language server be revived now that we've updated to the 3.17 spec ?

@CsCherrYY

Copy link
Copy Markdown
Contributor Author

Can this along with the change on the language server be revived now that we've updated to the 3.17 spec ?

I'm looking at this. The UX change (some UI limitation) of this PR is mentioned in #2376 (comment)

CsCherrYY and others added 3 commits October 26, 2026 12:35
vscode-languageclient's LanguageClient constructor already calls
registerBuiltinFeatures(), which registers TypeHierarchyFeature
internally. The explicit registration added here is not just redundant,
it no longer compiles: the package now restricts its exports map to
'.', './node', './browser', so the deep import
'vscode-languageclient/lib/common/typeHierarchy' is no longer a valid
module path, and TypeHierarchyFeature isn't re-exported from the public
API either.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
The LSP-based rewrite simplified TypeHierarchyTreeDataProvider down to
always resolving children eagerly before deciding collapsible state,
and dropped three refinements the pre-rewrite custom-protocol version
had:

- java.typeHierarchy.lazyLoad: the setting existed in package.json but
  nothing read it anymore, so toggling it had no effect.
- The java.lang.Object subtype placeholder: expanding Object with no
  placeholder would otherwise invoke typeHierarchy/subtypes for every
  class in the workspace.
- The shared getThemeIcon helper in themeUtils.ts, duplicated here as a
  private static copy instead of reused.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
@robstryker
robstryker force-pushed the cs-typehierarchy-impl branch from 819c31a to 26c0299 Compare October 26, 2026 16:57
@robstryker

Copy link
Copy Markdown
Contributor
  • Rebased onto current main (fixed a now-invalid TypeHierarchyFeature import — it's auto-registered now — and restored
    lazyLoad/java.lang.Object placeholder/shared icon helper that main gained since this was opened).
  • Test path: "Show Class Hierarchy" only (right-click or Command Palette) — that's the only command this PR touches.
  • "Show Supertype/Subtype Hierarchy" are a separate, untouched code path (native references-view commands) — fine as a
    baseline, not what needs testing here.
  • macOS CI failure was a plain network fetch timeout during test setup, unrelated to this change — Linux passed clean
    on the same commit; re-run should pass.

@robstryker

Copy link
Copy Markdown
Contributor

@datho7561 Manual test seems to work on the single testable code path. No obvious errors, expected behavior received. LMK what you think.

@datho7561

Copy link
Copy Markdown
Contributor

I'll try it out manually quickly, I think I saw that as of the current release there are two "Type Hierarchy" entries in the context meny so hopefully this resolves that.

@datho7561

Copy link
Copy Markdown
Contributor

It seems like this renames the first of the two "Show Type Hierarchy" entries to "Show Class Hierarchy". I don't fully understand what the difference is. They both appear to open the same view? With roughly the same information?

@datho7561

datho7561 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Ahh the class hierarchy doesn't show superinterfaces. Hmm I don't think this difference is all that exciting? I feel like supertypes is good enough in all cases?

The class hierarchy shows both sub and super types without having to toggle between the two, which I think on it's own is a helpful feature, and I prefer to the separate sub and super hierarchies.

However, having two separate context menu items and effectively three separate views is very confusing for the end user. I think we should migrate over to the standard VS Code-provided type hierarchy system. This will reduce the complexity of vscode-java and will be less confusing to end users.

@robstryker

Copy link
Copy Markdown
Contributor

Just gonna dump some claude analysis here bc i'm too tired to sumarize:

Here's the actual delegation chain for each:

  • "Show Supertype Hierarchy" / "Show Subtype Hierarchy" (ours) — these are thin wrappers. Their handlers literally
    just call commands.executeCommand(showSupertypeHierarchyReferenceViewCommand, location) /
    showSubtypeHierarchyReferenceViewCommand — i.e., they hand off directly to the same built-in references-view
    extension's own generic implementation that "Show Type Hierarchy" uses. So yes — these two of our three commands are
    genuinely redundant with the generic one: same underlying implementation, same UI, we're just giving it a
    Java-specific menu entry/title instead of making users find the generic one.
  • "Show Class Hierarchy" (ours) — this one is not a wrapper. It's real custom code (model.ts/util.ts) that calls
    client.sendRequest(TypeHierarchySupertypesRequest.type, ...)/TypeHierarchySubtypesRequest.type directly via
    vscode-languageclient, builds its own tree, and renders it in a custom references-view-hosted panel. The actual
    differentiator: it shows a single combined up+down tree (climb to root, then show the full subtree) in one view —
    something the generic capability can't do, since the standard LSP protocol only has separate supertypes/subtypes
    requests, no "both directions combined" concept. So this one earns its existence.

Your instinct is right for 2 of the 3: Supertype/Subtype Hierarchy are duplicated work — they add nothing over the
generic "Show Type Hierarchy" command except a Java-specific label, and now actively clutter the menu with
near-identical entries pointing at the same implementation. "Class Hierarchy" is the one piece of real, non-redundant
value this extension still provides. Worth raising as a cleanup candidate — dropping the two wrapper commands and
letting users just use the generic one, keeping only "Class Hierarchy" as vscode-java's actual contribution.

@robstryker

Copy link
Copy Markdown
Contributor

Here's some more:

The replacement click path:

  1. Right-click a class/symbol in the editor → "Show Type Hierarchy" (category "Types", command
    references-view.showTypeHierarchy). Requires editorHasTypeHierarchyProvider — true now that jdt.ls advertises the
    capability. This opens the References panel in Type Hierarchy mode.
  2. In that panel's title bar, there's a toggle: one button, either "Show Supertypes" ($(type-hierarchy-super) icon) or
    "Show Subtypes" ($(type-hierarchy-sub) icon) — only whichever direction you're not currently viewing is shown, so
    clicking it flips direction. One click to switch between the two, no need to go back to the editor.
  3. You can also right-click any node inside the tree itself and get the same "Show Supertypes"/"Show Subtypes" options
    there — that re-roots the hierarchy exploration at that specific node instead of your original starting symbol.

So the full replacement for our two custom commands: right-click → "Show Type Hierarchy" (1 click) → toggle button in
the panel title bar to pick supertypes or subtypes (1 click). Same click-depth as our custom commands, and arguably
better since switching direction doesn't require re-invoking from the editor each time — it's a toggle in the
already-open panel.

This also directly confirms the design intent I found earlier: VS Code's own team deliberately left the "combined
class view" out of this generic toggle UI, expecting single-inheritance languages like Java to provide their own —
which is exactly what vscode-java's "Class Hierarchy" command does, and exactly why dropping "Supertype"/"Subtype
Hierarchy" while keeping "Class Hierarchy" is the right cut: the generic commands are pure duplication with a worse UX
(can't toggle direction without re-invoking), while "Class Hierarchy" is real, non-duplicated value.

@datho7561

Copy link
Copy Markdown
Contributor

expecting single-inheritance languages like Java to provide their own

I don't think that's right whatsoever. They built VS Code to be a TypeScript IDE. JavaScript/TypeScript is also single inheritance. I think they didn't like our separate class hierarchy because it's redundant given there's already super and sub type hierarchies. The separate class hierarchy is more a hold over from Eclipse, from what I understand.

I'll file a new issue and do a write up explaining what I think is needed for this change.

@robstryker

Copy link
Copy Markdown
Contributor

Closing this, as we've opted to go in a different direction.

@robstryker robstryker closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants