prometeu-studio/discussion/lessons/DSC-0039-pbs-lsp-go-to-definition/LSN-0068-pbs-go-to-definition-uses-editorial-lookup-and-physical-files.md
bQUARKz c2112f6ee1
Some checks are pending
Intrepid/Prometeu/Studio/pipeline/pr-master Build started...
JaCoCo Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 62.22% (17996/28921) * Branch Coverage: 52.87% (6986/13213) * Lines of Code: 28921 * Cyclomatic Complexity: 11624 #### Quality Gates Summary Output truncated.
Test / Build skipped: 15, passed: 659
Intrepid/Prometeu/Studio/pipeline/head This commit looks good
implements PLN-0131
Add PBS go-to-definition as hover editorial lookup plus physical
declaration locations on FrontendLanguageService. Empty results stay
honest when the target is not a regular file, including virtual stdlib
paths.

Housekeep DSC-0039 with LSN-0068.
2026-09-21 07:50:14 +01:00

99 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: LSN-0068
ticket: pbs-lsp-go-to-definition
title: PBS go-to-definition uses editorial lookup and physical files
created: 2026-09-21
tags: [studio, lsp, vscode, compiler-pbs, editor, definition]
---
# PBS go-to-definition uses editorial lookup and physical files
## Original Problem
PBS editor assistance already had compiler-backed completion, hover, and signature help (`LSN-0051`). Users still could not jump from a use to a declaration. Wave 1 explicitly deferred `go to definition`.
The remaining LSP navigation family (references, rename, workspace symbols, document links, hierarchy) needed a destination policy before those features could be honest. The risk was shipping a text search, a new `SymbolId` index, or virtual documents for stdlib before a real physical target existed.
## Consolidated Decision
PBS Go to Definition is the LSP projection of **physical declaration locations** on top of the **same editorial lookup hover already uses**.
Durable locks from `DEC-0052`:
1. Resolve the identifier under the cursor through the hover path (locals, parameters, members, imports/supplementals, current-module top-level). Do not use text search or a new usage index.
2. Keep the capability on the existing aggregated `FrontendLanguageService`. Add a default-empty `definition` method and a generic location DTO. Do not add a Definition SPI.
3. Map PBS editorial spans inside `prometeu-frontend-pbs`. Common LSP must not import `p.studio.compiler.pbs.*`.
4. Jump only when `Span.fileId` maps to a **regular filesystem file**. Otherwise return an empty list. Do not create virtual documents, `untitled:` buffers, or synthetic URIs.
5. The destination is the canonical declaration, not the import-alias line. Overloads return every matching location.
6. Advertise `definitionProvider`. Partial coverage is valid. Keywords, source-less builtins, unresolved names, and virtual stdlib paths stay empty; hover is unchanged.
7. Analysis stays request-local, like hover. This discussion does not build references, rename, or snapshot cache.
Spec 23 §8.3 already listed definition as an optional editor capability. It now also states: a definition location must identify a compiler-known physical source file, or the response must be empty.
## Final Implementation
| Layer | What landed |
|---|---|
| PBS editorial | `PbsEditorialSupportService.definition` reuses hover dispatch and attaches declaration `Span`s (`PbsEditorialLocation`). |
| Generic contract | `FrontendDefinitionLocation` (absolute path + offsets) and `FrontendLanguageService.definition` defaulting to `List.of()`. |
| PBS mapping | `PBSFrontendLanguageService` maps `FileId` through `fileTable` and keeps the location only if `Files.isRegularFile(path)`. |
| LSP | `LanguageServiceBridge.definition`, `definitionProvider`, `textDocument/definition`. Compile-only frontends return empty. |
| VS Code | Unchanged thin client. |
Stdlib and SDK modules are still registered under virtual paths such as `/virtual/stdlib/...`. Those handles are not regular files, so F12 on `Gfx.clear` is empty even though hover works. That is the physical-file rule, not a missing lookup.
The location payload (path + span of an already resolved symbol) is reusable later by references (`AGD-0043`) and rename (`AGD-0046`). Those indexes were not built here. Snapshots (`AGD-0051`) remain a later performance discussion, not a prerequisite for this request-local feature.
## Examples
Same-file jump:
```pbs
fn helper() -> int { return 42; }
fn frame() -> void {
helper(); // definition -> helper's declaration in this file
}
```
Aliased import jumps to the original declaration span, not the `import` line:
```pbs
import { Log as Logger } from @sdk:log;
Logger.info("hello");
```
If `@sdk:log` is only a virtual stdlib handle, definition is empty. If a project file owns the declaration and that file exists on disk, definition uses that path.
Builtins stay hover-only:
```pbs
let n: int = 1; // hover describes the builtin; definition is empty
```
## Pitfalls
Do not implement definition as a second name search in `lsp-v1` or in the VS Code extension. It will break on imports, overloads, and members, then be thrown away when references arrive.
Do not open `/virtual/stdlib/...` or invent an `untitled:` document so stdlib F12 “does something”. Empty is the honest result until those sources are real files.
Do not pick the first overload location in the server. Return the full `Location[]`.
Do not wait for snapshot cache before definition. Hover is already request-local; definition follows that shape.
Do not split a new top-level definition service “for future languages”. PBS is a real consumer of the existing language-service surface (`LSN-0067`).
Do not treat this lesson as closing references, rename, outline, workspace symbols, or document links. Those agendas stay open. This lesson only locks the destination policy they can reuse.
## References
- Agenda: `AGD-0042` (Q1Q6 = A)
- Decision: `DEC-0052`
- Plan: `PLN-0131`
- Spec 23 §8.3 — optional definition capability; physical-file-or-empty
- `LSN-0051` — wave 1 deferred go-to-definition
- `LSN-0058` — generic `FrontendLanguageService` for LSP
- `LSN-0047` — protocol stays in `lsp-v1`; compiler owns semantics
- `LSN-0067` — no SPI or virtual-document host without a real consumer
- Still open: `AGD-0043` references, `AGD-0045` workspace symbols, `AGD-0046` rename, `AGD-0051` snapshots, `AGD-0055` document links, `AGD-0056` hierarchy