TML-2946: Add PSL type and generic block completions#871
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (9)
📒 Files selected for processing (7)
💤 Files with no reviewable changes (7)
📝 WalkthroughWalkthroughAdds PSL completion classification, completion item generation, and LSP completion wiring to the language server. Tests cover classifier outcomes, completion item results, and server-level completion requests. README text is updated to describe the new completion scope and flow. ChangesPrisma Next language-server completion
Sequence Diagram(s)sequenceDiagram
participant LSPClient as LSP client
participant Connection as connection.onCompletion
participant CompleteDocument as completeDocument
participant Artifacts as project.artifacts
participant Classifier as classifyPslCompletionContext
participant Provider as providePslCompletionItems
LSPClient->>Connection: textDocument/completion
Connection->>CompleteDocument: uri + position
CompleteDocument->>Artifacts: read cached document/source and symbol table
CompleteDocument->>Classifier: classify cursor context
CompleteDocument->>Provider: generate completion items
Provider-->>CompleteDocument: CompletionItem[]
CompleteDocument-->>LSPClient: completion list or []
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@prisma-next/extension-author-tools
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@prisma-next/middleware-cache
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/extension-postgis
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/extension-supabase
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/cli-telemetry
@prisma-next/config-loader
@prisma-next/emitter
@prisma-next/language-server
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
size-limit report 📦
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/1-framework/3-tooling/language-server/README.md`:
- Around line 37-39: The server module description is incomplete because it only
mentions model field type completions and omits the generic-block parameter-key
completions that `createServer(connection)` also wires up. Update the
`server.ts` bullet in the README so it reflects both supported completion
contexts, matching the behavior described in `completion-context.ts` and
`completion-provider.ts`.
In `@packages/1-framework/3-tooling/language-server/src/server.ts`:
- Around line 253-295: Refresh the completion path in completeDocument so it
does not rely on stale cached parse artifacts from
project.artifacts.getDocument(uri) when the buffer has just changed. Before
calling classifyPslCompletionContext(), rebuild or refresh the document
artifacts from the current document.getText() and use those updated artifacts
for the completion context and providePslCompletionItems call, while keeping the
existing early returns and try/catch behavior intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: b388a8f7-7b3e-4afb-a96d-db96126c5a9d
⛔ Files ignored due to path filters (9)
projects/lsp-autocomplete/plan.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/dispatches/01-cursor-classifier-substrate.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/dispatches/02-model-type-provider.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/dispatches/03-lsp-completion-route.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/dispatches/04-scope-docs-and-final-guardrails.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/plan.mdis excluded by!projects/**projects/lsp-autocomplete/slices/model-type-completions/spec.mdis excluded by!projects/**projects/lsp-autocomplete/spec.mdis excluded by!projects/**projects/lsp-autocomplete/trace.jsonlis excluded by!projects/**
📒 Files selected for processing (7)
packages/1-framework/3-tooling/language-server/README.mdpackages/1-framework/3-tooling/language-server/src/completion-context.tspackages/1-framework/3-tooling/language-server/src/completion-provider.tspackages/1-framework/3-tooling/language-server/src/server.tspackages/1-framework/3-tooling/language-server/test/completion-context.test.tspackages/1-framework/3-tooling/language-server/test/completion-provider.test.tspackages/1-framework/3-tooling/language-server/test/server.test.ts
| - `completion-context.ts` — pure cursor classifier for PSL completion contexts, currently routing model field type positions and descriptor-backed generic block parameter-key positions while marking everything outside slice scope unsupported. | ||
| - `completion-provider.ts` — pure completion item provider for supported model field type and generic block parameter contexts. | ||
| - `server.ts` — `createServer(connection)` wires diagnostics, whole-document formatting, and narrow model field type completion handlers onto an injected connection. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Update the server.ts module description to include generic-block completions.
This bullet now understates the server wiring: the README above documents generic block parameter-key completion too, and server.ts registers a single completion handler for both supported contexts. As per coding guidelines, "Keep docs current (READMEs, rules, links)".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/1-framework/3-tooling/language-server/README.md` around lines 37 -
39, The server module description is incomplete because it only mentions model
field type completions and omits the generic-block parameter-key completions
that `createServer(connection)` also wires up. Update the `server.ts` bullet in
the README so it reflects both supported completion contexts, matching the
behavior described in `completion-context.ts` and `completion-provider.ts`.
Source: Coding guidelines
| async function completeDocument(uri: string, position: Position): Promise<CompletionItem[]> { | ||
| const document = documents.get(uri); | ||
| if (document === undefined) { | ||
| return []; | ||
| } | ||
|
|
||
| let project: ProjectState | undefined; | ||
| try { | ||
| project = await resolveProjectForDocument(uri); | ||
| } catch { | ||
| return []; | ||
| } | ||
| if (project === undefined || !project.inputs.includes(uri)) { | ||
| return []; | ||
| } | ||
|
|
||
| const cached = project.artifacts.getDocument(uri); | ||
| const symbolTable = project.artifacts.getSymbolTable(); | ||
| if (cached === undefined || symbolTable === undefined) { | ||
| return []; | ||
| } | ||
|
|
||
| try { | ||
| const context = classifyPslCompletionContext({ | ||
| document: cached.document, | ||
| sourceFile: cached.sourceFile, | ||
| position, | ||
| }); | ||
| return [ | ||
| ...providePslCompletionItems({ | ||
| context, | ||
| sourceFile: cached.sourceFile, | ||
| candidates: { | ||
| scalarTypes: project.controlStack.scalarTypes, | ||
| pslBlockDescriptors: project.controlStack.pslBlockDescriptors, | ||
| symbolTable, | ||
| }, | ||
| }), | ||
| ]; | ||
| } catch { | ||
| return []; | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Refresh artifacts from the current buffer before classifying completions.
Line 269 reads cached parse artifacts, but those artifacts are only refreshed asynchronously in publish() after onDidChangeContent. A completion request that lands right after typing can therefore run against the previous buffer and return wrong items/ranges or []. Rebuild or refresh the artifacts from document.getText() on this path before calling classifyPslCompletionContext().
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/1-framework/3-tooling/language-server/src/server.ts` around lines
253 - 295, Refresh the completion path in completeDocument so it does not rely
on stale cached parse artifacts from project.artifacts.getDocument(uri) when the
buffer has just changed. Before calling classifyPslCompletionContext(), rebuild
or refresh the document artifacts from the current document.getText() and use
those updated artifacts for the completion context and providePslCompletionItems
call, while keeping the existing early returns and try/catch behavior intact.
Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
Signed-off-by: Serhii Tatarintsev <tatarintsev@prisma.io>
Linked issue
Refs TML-2946
At a glance
At the
author |model field type position,textDocument/completionreturns configured scalar types plus visible model/composite/type-alias candidates such asBoolean,DateTime,Int,String,Post,User, andAddress, plus namespace qualifiers such asauth.. After the user types or accepts a namespace qualifier, positions likeauth.|complete model/composite members inside that namespace. At descriptor-backed generic block parameter-key positions likewh|, it returns declared block parameters such aswhereand filters out sibling keys that already exist in the block.Decision
This PR ships the first PSL autocomplete surfaces in
@prisma-next/language-server: configured PSL model field type completions and descriptor-backed generic block parameter-key completions. It adds a typed cursor classifier over cached parser artifacts, completion providers backed by configured scalars, the current project symbol table, and the project control-stack PSL block descriptors, an LSP completion route, and README/guardrail coverage for the intentionally narrow scope.Summary
The language server now answers completion requests for open configured PSL documents at model field type positions and descriptor-backed generic block parameter-key positions. Unsupported contexts stay empty, including ordinary PSL
@/@@attributes, attribute arguments, generic block parameter values, unconfigured documents, relation-aware scenarios, and external contract-space discovery gaps.Reviewer notes
completion-context.tsowns the cursor-context boundary: token lookup, ancestor rejection, blank model type positions, partial qualified names, generic block body/key detection, and explicit unsupported reasons.ref,option,value, orlistdescriptors remain out of scope.projects/lsp-autocomplete/**is included for Drive traceability: it contains the project/slice specs, dispatch briefs, and trace for this project. Close-out removes/migrates project artifacts after the overall project is done.How it fits together
DocumentAst/SourceFiledata into either a model-field-type context, a generic-block-parameter context, or an explicit unsupported reason. This keeps completion on the existing recovered CST/AST path instead of reparsing with a marker.CompletionItems for configured scalars, top-level model/composite/scalar/type-alias symbols, bare namespace qualifier candidates such asauth., and namespace-local model/composite members only after a qualifier is present. For generic blocks, it resolves the descriptor by block keyword and returns declared parameter keys that match the typed prefix.completionProviderand routestextDocument/completionthrough the same configured-input and cached-artifact ownership checks used by diagnostics/formatting, passing both the project symbol table andpslBlockDescriptorsinto the provider.Behavior changes & evidence
Configured PSL inputs now complete model field type positions. The server advertises completion and routes requests only after it finds an open configured document, cached parse artifacts, and a project symbol table.
packages/1-framework/3-tooling/language-server/src/server.ts,packages/1-framework/3-tooling/language-server/src/completion-context.ts,packages/1-framework/3-tooling/language-server/src/completion-provider.tspackages/1-framework/3-tooling/language-server/test/server.test.ts,packages/1-framework/3-tooling/language-server/test/completion-context.test.ts,packages/1-framework/3-tooling/language-server/test/completion-provider.test.tsDescriptor-backed generic block parameter keys now complete. The classifier identifies blank and partial key positions inside
GenericBlockDeclarationAstbodies, the provider resolves the matchingAuthoringPslBlockDescriptor, and completions exclude already-present sibling keys.packages/1-framework/3-tooling/language-server/src/completion-context.ts,packages/1-framework/3-tooling/language-server/src/completion-provider.ts,packages/1-framework/3-tooling/language-server/src/server.tspackages/1-framework/3-tooling/language-server/test/completion-context.test.ts,packages/1-framework/3-tooling/language-server/test/completion-provider.test.ts,packages/1-framework/3-tooling/language-server/test/server.test.tsModel type candidates are stable and scoped to visible type-like symbols. The provider orders configured scalars before top-level candidates and namespace qualifiers, filters prefixes, completes namespace qualifiers such as
auth.before namespace-local model names, and excludes generic block symbols from model-field-type completions.packages/1-framework/3-tooling/language-server/src/completion-provider.tspackages/1-framework/3-tooling/language-server/test/completion-provider.test.tsQualified type positions preserve the typed shape. Bare namespace prefixes like
a|replace the typed segment withauth., namespace-qualified positions likeauth.U|complete only the typed member segment, and contract-space-qualified positions likesupabase:auth.P|replace only the typed name segment and use currently visible candidates.packages/1-framework/3-tooling/language-server/src/completion-context.ts,packages/1-framework/3-tooling/language-server/src/completion-provider.tspackages/1-framework/3-tooling/language-server/test/completion-context.test.ts,packages/1-framework/3-tooling/language-server/test/completion-provider.test.tsUnsupported contexts return
[]instead of misleading suggestions. Unconfigured documents, ordinary field/model attributes, attribute arguments, generic block parameter values, comments, constructor arguments, and other non-type/non-key positions are rejected before provider output reaches the client.packages/1-framework/3-tooling/language-server/src/completion-context.ts,packages/1-framework/3-tooling/language-server/src/server.tspackages/1-framework/3-tooling/language-server/test/server.test.ts,packages/1-framework/3-tooling/language-server/test/completion-context.test.tsThe supported editor surface is documented. The README now says completion is supported for configured PSL model field type positions and descriptor-backed generic block parameter-key positions, and explicitly excludes ordinary attributes, attribute arguments, generic block parameter values, relation-aware suggestions, and external contract-space discovery.
packages/1-framework/3-tooling/language-server/README.mdCompatibility / migration / risk
No contract emission, runtime, migration, adapter, or public TypeScript API behavior changes are expected. The main risk is editor-surface false positives; this PR mitigates it by returning
[]outside configured model field type and descriptor-backed generic block parameter-key positions.Testing performed
pnpm --filter @prisma-next/framework-components build— passed; rebuilt missing localdist/needed by language-server tests in this worktreepnpm --filter @prisma-next/language-server test— 9 files / 103 tests passedpnpm --filter @prisma-next/language-server typecheck— passedpnpm --filter @prisma-next/language-server lint— passed, 26 files checkedSkill update
n/a — no reusable agent skill update is required. The language-server README documents the new editor-facing behavior and exclusions.
Follow-ups
ref,option,value,list) at the value cursor position.Alternatives considered
@/@@attributes are a different surface from descriptor-backed generic block parameters.Checklist
git commit -s) per the DCO. The DCO status check will block merge if any commit is missing aSigned-off-by:trailer.n/aif the change is doc-only / refactor with no behavioural delta).TML-NNNN: <sentence-case title>form (Linear ticket prefix + concise title naming the concrete deliverable). See.claude/skills/create-pr/SKILL.mdfor the full convention.n/a — internal only).Summary by CodeRabbit