Skip to content

feat: go-to-definition for dependencies in abstract graph classes#282

Open
guyca wants to merge 14 commits intomasterfrom
feat/go-to-definition-abstract-graphs
Open

feat: go-to-definition for dependencies in abstract graph classes#282
guyca wants to merge 14 commits intomasterfrom
feat/go-to-definition-abstract-graphs

Conversation

@guyca
Copy link
Collaborator

@guyca guyca commented Feb 27, 2026

vscode-language-server-obsidian: fix cmd-click navigation when the enclosing graph class is abstract (no @graph decorator) and the dependency is declared as an abstract method in a parent abstract class.

Root causes fixed:

  • getParentGraphRecursive only recognised classes decorated with @graph. Abstract graph classes without the decorator were invisible to the language server, causing navigation to silently return undefined.
  • resolveProvider only searched a graph's own @provides() methods and subgraphs. It never walked the base class chain, so a dependency declared as an abstract method in a parent class could never be resolved.

Changes:

  • graphs.tsgetParentGraphRecursive now accepts any enclosing ClassDeclaration as a graph (the isProviderDependency() gate already guarantees we are inside a @provides() method)
  • graph.tsresolveProvider now delegates to the base class via a new resolveProviderOrAbstract path that checks both @provides() methods and abstract method declarations
  • New integration test dependencyInAbstractBaseGraph covering the full scenario

react-obsidian: allow @graph decorator on abstract classes

  • Added AbstractConstructor type (abstract new (...args: any[]) => any) — a supertype covering both abstract and concrete constructors
  • Broadened @graph decorator generic bound from Constructor to AbstractConstructor, making it valid to annotate abstract graph classes (e.g. for ESLint plugin dependency resolution)
  • Registration in GraphRegistry is unchanged — harmless on abstract classes since they are never instantiated by the DI runtime
  • New acceptance test covering @graph applied directly to an abstract class

eslint-plugin-obsidian: fix false unresolved-provider-dependencies errors on abstract port graphs

  • resolveProviders() in graph.ts previously only collected @provides-decorated methods from the base class. Abstract methods without a decorator (the contract pattern used by abstract port graphs) were never added to the provider pool, producing false errors on every provider that consumed them.
  • Added resolveBaseGraphProviders() that collects both decorated and abstract methods, recursively walking the full base class chain — mirroring the existing resolveProviderOrAbstract() logic used by the single-name lookup path.
  • New valid fixture validGraphWithAbstractBaseProvider.ts covering the pattern.

Fix cmd-click navigation for @provides() parameters when the enclosing
class is abstract (no @graph decorator) and the dependency is declared
as an abstract method in a parent abstract class.

Two bugs fixed:
- getParentGraphRecursive now recognises any enclosing ClassDeclaration
  as a graph, not just classes decorated with @graph
- resolveProvider now walks the base class chain and finds abstract
  method declarations as provider definitions
The server package was pinned to 2.27.0 which doesn't include the new
findAbstractProvider/resolveProviderOrAbstract methods added in graph.ts.
CI fetches the published npm version on a clean install, so the new
go-to-definition test was failing there despite passing locally.
@guyca guyca force-pushed the feat/go-to-definition-abstract-graphs branch from 8625adb to 12c510b Compare February 28, 2026 07:59
- Add AbstractConstructor type (abstract new (...args: any[]) => any) to types/index.ts
- Broaden graph decorator generic bound from Constructor to AbstractConstructor
- Cast to Constructable<ObjectGraph> when calling register (abstract classes
  are never instantiated by the DI runtime; registration is harmless)
- Add acceptance test covering @graph on an abstract class
@guyca guyca force-pushed the feat/go-to-definition-abstract-graphs branch from 12c510b to 1ae7987 Compare February 28, 2026 08:03
…providers

resolveProviders() in graph.ts only included @provides-decorated methods
from the base class. Abstract methods without a decorator (the contract
pattern used by abstract port graphs) were never added to the provider pool,
causing false unresolved-provider-dependencies errors.

Add resolveBaseGraphProviders() that collects both decorated and abstract
methods recursively up the base class chain, mirroring the existing
resolveProviderOrAbstract() logic used by the single-name lookup path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant