Add cross-package TypeScript reference support via additional_workspace_folders#1418
Add cross-package TypeScript reference support via additional_workspace_folders#1418meirLixen wants to merge 5 commits intooraios:mainfrom
Conversation
…ce_folders The TypeScript language server was initialized with a single workspace folder, so tsserver could not discover references across sibling packages in a monorepo. This adds an `additional_workspace_folders` setting in `ls_specific_settings["typescript"]` that accepts a list of directory paths. Each folder is registered as an LSP workspace folder during initialization, and a representative .ts file is opened from each to trigger tsserver project loading. This enables `find_referencing_symbols` and `request_references` to return results from across package boundaries. Supporting changes in the base SolidLanguageServer class: - Add `_is_cross_workspace_path()` and `_resolve_file_uri()` helpers to canonicalize URIs for paths containing '..' segments - Apply consistent URI resolution across all LSP request methods (definitions, references, completions, document symbols, rename, insert/delete text) to prevent URI mismatches with cross-workspace files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MischaPanch
left a comment
There was a problem hiding this comment.
Thanks for the PR. Is there a reason why we can't do that centrally in the base class, such that it works for all language servers?
meirLixen
left a comment
There was a problem hiding this comment.
Good question! The URI normalization (_is_cross_workspace_path / _resolve_file_uri) is already in the base SolidLanguageServer class and works for all language servers.
The TS-specific part is the additional_workspace_folders configuration and the file-opening logic in _open_additional_workspace_files. This is TS-specific because:
- LSP workspace folder initialization differs per server — each language server subclass builds its own
_get_initialize_params(), and not all language servers support multi-root workspaces the same way - tsserver requires explicit file opening to load projects — other language servers (e.g. Java/jdtls, Rust/rust-analyzer) may handle project discovery differently
- The representative file finder (
_find_representative_ts_file) looks for.ts/.tsxfiles neartsconfig.json
That said, moving the workspace folder resolution to the base class (with per-language override hooks for the file-opening strategy) would be a natural next step if other language servers need this. Happy to refactor if you'd prefer that approach.
|
Yes, pls refactor this to be future proof, even if the implementation will only work for typescript now. Pls change the logic such that the user can always provide the config in a uniform way, so we have a fixed API for users for providing additional workspaces. Then add methods in the base class where needed which raise if this option is not supported/implemented yet, and override the methods accordingly in typescript. Alternatively, you could task an agent with actually implementing and testing it for the most important LS. You could investigate whether it makes sense to post-process the initialization params and include the workspaces in a default fashion directly in the base class, overriding the default behavior where needed. But I don't know the best way to handle this, so I'll leave proposing the most suitable design to you at this stage - so this is just a suggestion to consider. @opcode81 and might go back to proposing a different structure after your initial proposal, but we don't have time to dive into it ourselves now. Since this is a significant extension, it should be thoroughly documented in our docs and in the changelog as well. Thanks for laying the groundwork for this! |
|
@meirLixen just FYI - the JetBrains variant of Serena has first-class support for all external dependencies out of the box |
…m API - Move additional_workspace_folders from TS-specific ls_specific_settings to a top-level project.yml setting and SolidLSPSettings field - Add base class methods in SolidLanguageServer: _resolve_additional_workspace_folders, _build_workspace_folders_param, _activate_additional_workspaces, _find_representative_source_file (raises NotImplementedError), _signal_expect_indexing, _wait_for_additional_workspace_indexing - TypeScript overrides only _find_representative_source_file and the indexing hooks - Update project.template.yml with documented setting - Add CHANGELOG entry
|
Refactored as requested in c1a72a7:
Adding support for another language server would only require overriding |
- Add 'Additional Workspace Folders' section to project configuration docs - Add cross-reference note to TypeScript LS settings section - Include configuration example and usage notes
Closes #750 (partially)
Related to #1260
Summary
additional_workspace_folderssetting inls_specific_settings["typescript"]to enable cross-packagefind_referencing_symbolsandrequest_referencesin monorepos.tsfile is opened to trigger tsserver project loading_is_cross_workspace_path()/_resolve_file_uri()helpers in the baseSolidLanguageServerclass to canonicalize URIs for paths with..segments, applied consistently across all LSP request methodsConfiguration
Paths can be absolute or relative to the project root. Results are cached, deduplicated, and validated (non-existent paths are skipped with a warning, paths overlapping with the repo root are ignored).
How it works
workspaceFoldersarray.tsfile from each folder is opened viadidOpento trigger tsserver project loading (tsserver only loads projects on-demand)open_file_bufferswith permanent ref_count to stay open for the server lifetime../other-package/src/file.ts) are resolved to canonical URIs via_resolve_file_uri()to prevent mismatches between tsserver-returned URIs and Serena-computed URIsTest plan
test_cross_package_find_references— verifiesrequest_referencesfinds refs across packagestest_cross_package_referencing_symbols— verifiesrequest_referencing_symbolsresolves containing symbols across packagestest_without_additional_workspace_no_cross_refs— baseline confirming cross-refs don't appear without config..detection