@prisma-next/language-server
Advanced tools
| import type { NamedTypeSymbol } from '@prisma-next/psl-parser'; | ||
| /** | ||
| * Presentation-level classification of a `types {}` binding: a | ||
| * non-constructor binding whose base is a configured scalar type refines that | ||
| * scalar (rendered as a default-library type); everything else reads as a | ||
| * plain alias. The authoritative scalar-or-not pronouncement lives in the | ||
| * interpreter's named-type resolution — this mirrors it for display only. | ||
| */ | ||
| export function refinesScalarType( | ||
| symbol: NamedTypeSymbol, | ||
| scalarTypes: readonly string[], | ||
| ): boolean { | ||
| return ( | ||
| !symbol.isConstructor && symbol.baseType !== undefined && scalarTypes.includes(symbol.baseType) | ||
| ); | ||
| } |
+27
-12
@@ -246,2 +246,14 @@ import { fileURLToPath, pathToFileURL } from "node:url"; | ||
| //#endregion | ||
| //#region src/named-type-classification.ts | ||
| /** | ||
| * Presentation-level classification of a `types {}` binding: a | ||
| * non-constructor binding whose base is a configured scalar type refines that | ||
| * scalar (rendered as a default-library type); everything else reads as a | ||
| * plain alias. The authoritative scalar-or-not pronouncement lives in the | ||
| * interpreter's named-type resolution — this mirrors it for display only. | ||
| */ | ||
| function refinesScalarType(symbol, scalarTypes) { | ||
| return !symbol.isConstructor && symbol.baseType !== void 0 && scalarTypes.includes(symbol.baseType); | ||
| } | ||
| //#endregion | ||
| //#region src/completion-provider.ts | ||
@@ -372,3 +384,3 @@ const categoryOrder = { | ||
| ...configuredScalarCandidates(source.scalarTypes), | ||
| ...topLevelSymbolCandidates(source.symbolTable), | ||
| ...topLevelSymbolCandidates(source.symbolTable, source.scalarTypes), | ||
| ...allNamespaceCandidates(source.symbolTable) | ||
@@ -408,9 +420,12 @@ ]); | ||
| } | ||
| function topLevelSymbolCandidates(symbolTable) { | ||
| function topLevelSymbolCandidates(symbolTable, scalarTypes) { | ||
| const { topLevel } = symbolTable; | ||
| const namedTypes = Object.values(topLevel.namedTypes); | ||
| const scalarRefinementNames = namedTypes.filter((symbol) => refinesScalarType(symbol, scalarTypes)).map((symbol) => symbol.name).sort(compareNames); | ||
| const aliasNames = namedTypes.filter((symbol) => !refinesScalarType(symbol, scalarTypes)).map((symbol) => symbol.name).sort(compareNames); | ||
| return [ | ||
| ...symbolCandidates(recordNames(topLevel.models), "topLevelModel", "Model", CompletionItemKind.Class), | ||
| ...symbolCandidates(recordNames(topLevel.compositeTypes), "topLevelCompositeType", "Composite type", CompletionItemKind.Struct), | ||
| ...symbolCandidates(recordNames(topLevel.scalars), "scalar", "Scalar type", CompletionItemKind.Unit), | ||
| ...symbolCandidates(recordNames(topLevel.typeAliases), "typeAlias", "Type alias", CompletionItemKind.Reference) | ||
| ...symbolCandidates(scalarRefinementNames, "scalar", "Scalar type", CompletionItemKind.Unit), | ||
| ...symbolCandidates(aliasNames, "typeAlias", "Type alias", CompletionItemKind.Reference) | ||
| ]; | ||
@@ -502,3 +517,3 @@ } | ||
| return { | ||
| scalarTypes: [...stack.scalarTypeDescriptors.keys()], | ||
| scalarTypes: [...stack.scalarTypes], | ||
| pslBlockDescriptors: stack.authoringContributions.pslBlockDescriptors | ||
@@ -515,3 +530,2 @@ }; | ||
| composedExtensionContracts: stack.extensionContracts, | ||
| scalarTypeDescriptors: stack.scalarTypeDescriptors, | ||
| authoringContributions: stack.authoringContributions, | ||
@@ -576,3 +590,2 @@ codecLookup: stack.codecLookup, | ||
| sourceFile, | ||
| scalarTypes: inputs.scalarTypes, | ||
| pslBlockDescriptors: inputs.pslBlockDescriptors | ||
@@ -657,3 +670,2 @@ }); | ||
| sourceFile: artifacts.sourceFile, | ||
| scalarTypes: controlStack.scalarTypes, | ||
| pslBlockDescriptors: controlStack.pslBlockDescriptors | ||
@@ -927,7 +939,8 @@ }).table; | ||
| if (Object.hasOwn(table.topLevel.compositeTypes, name)) return { tokenType: "struct" }; | ||
| if (Object.hasOwn(table.topLevel.scalars, name)) return { | ||
| const namedType = table.topLevel.namedTypes[name]; | ||
| if (namedType !== void 0) return refinesScalarType(namedType, source.scalarTypes) ? { | ||
| tokenType: "type", | ||
| modifierBitset: semanticTokenModifierBits.defaultLibrary | ||
| }; | ||
| if (Object.hasOwn(table.topLevel.typeAliases, name) || Object.hasOwn(table.topLevel.blocks, name)) return { tokenType: "type" }; | ||
| } : { tokenType: "type" }; | ||
| if (Object.hasOwn(table.topLevel.blocks, name)) return { tokenType: "type" }; | ||
| if (source.scalarTypes.includes(name)) return { | ||
@@ -1216,3 +1229,5 @@ tokenType: "type", | ||
| if (disposed) return; | ||
| connection.console.error(error instanceof Error ? error.message : String(error)); | ||
| try { | ||
| connection.console.error(error instanceof Error ? error.message : String(error)); | ||
| } catch {} | ||
| }); | ||
@@ -1219,0 +1234,0 @@ } |
+10
-10
| { | ||
| "name": "@prisma-next/language-server", | ||
| "version": "0.16.0-dev.11", | ||
| "version": "0.16.0-dev.13", | ||
| "license": "Apache-2.0", | ||
@@ -9,8 +9,8 @@ "type": "module", | ||
| "dependencies": { | ||
| "@prisma-next/config": "0.16.0-dev.11", | ||
| "@prisma-next/config-loader": "0.16.0-dev.11", | ||
| "@prisma-next/errors": "0.16.0-dev.11", | ||
| "@prisma-next/framework-components": "0.16.0-dev.11", | ||
| "@prisma-next/psl-parser": "0.16.0-dev.11", | ||
| "@prisma-next/utils": "0.16.0-dev.11", | ||
| "@prisma-next/config": "0.16.0-dev.13", | ||
| "@prisma-next/config-loader": "0.16.0-dev.13", | ||
| "@prisma-next/errors": "0.16.0-dev.13", | ||
| "@prisma-next/framework-components": "0.16.0-dev.13", | ||
| "@prisma-next/psl-parser": "0.16.0-dev.13", | ||
| "@prisma-next/utils": "0.16.0-dev.13", | ||
| "pathe": "^2.0.3", | ||
@@ -21,5 +21,5 @@ "vscode-languageserver": "10.1.0", | ||
| "devDependencies": { | ||
| "@prisma-next/test-utils": "0.16.0-dev.11", | ||
| "@prisma-next/tsconfig": "0.16.0-dev.11", | ||
| "@prisma-next/tsdown": "0.16.0-dev.11", | ||
| "@prisma-next/test-utils": "0.16.0-dev.13", | ||
| "@prisma-next/tsconfig": "0.16.0-dev.13", | ||
| "@prisma-next/tsdown": "0.16.0-dev.13", | ||
| "@types/node": "25.9.4", | ||
@@ -26,0 +26,0 @@ "tsdown": "0.22.8", |
@@ -19,2 +19,3 @@ import { | ||
| } from './completion-context'; | ||
| import { refinesScalarType } from './named-type-classification'; | ||
@@ -278,3 +279,3 @@ export interface PslCompletionCandidateSource { | ||
| ...configuredScalarCandidates(source.scalarTypes), | ||
| ...topLevelSymbolCandidates(source.symbolTable), | ||
| ...topLevelSymbolCandidates(source.symbolTable, source.scalarTypes), | ||
| ...allNamespaceCandidates(source.symbolTable), | ||
@@ -339,4 +340,14 @@ ]); | ||
| symbolTable: SymbolTable, | ||
| scalarTypes: readonly string[], | ||
| ): readonly ModelTypeCompletionCandidate[] { | ||
| const { topLevel } = symbolTable; | ||
| const namedTypes = Object.values(topLevel.namedTypes); | ||
| const scalarRefinementNames = namedTypes | ||
| .filter((symbol) => refinesScalarType(symbol, scalarTypes)) | ||
| .map((symbol) => symbol.name) | ||
| .sort(compareNames); | ||
| const aliasNames = namedTypes | ||
| .filter((symbol) => !refinesScalarType(symbol, scalarTypes)) | ||
| .map((symbol) => symbol.name) | ||
| .sort(compareNames); | ||
| return [ | ||
@@ -355,14 +366,4 @@ ...symbolCandidates( | ||
| ), | ||
| ...symbolCandidates( | ||
| recordNames(topLevel.scalars), | ||
| 'scalar', | ||
| 'Scalar type', | ||
| CompletionItemKind.Unit, | ||
| ), | ||
| ...symbolCandidates( | ||
| recordNames(topLevel.typeAliases), | ||
| 'typeAlias', | ||
| 'Type alias', | ||
| CompletionItemKind.Reference, | ||
| ), | ||
| ...symbolCandidates(scalarRefinementNames, 'scalar', 'Scalar type', CompletionItemKind.Unit), | ||
| ...symbolCandidates(aliasNames, 'typeAlias', 'Type alias', CompletionItemKind.Reference), | ||
| ]; | ||
@@ -369,0 +370,0 @@ } |
@@ -51,3 +51,3 @@ import type { ContractSourceContext } from '@prisma-next/config/config-types'; | ||
| return { | ||
| scalarTypes: [...stack.scalarTypeDescriptors.keys()], | ||
| scalarTypes: [...stack.scalarTypes], | ||
| pslBlockDescriptors: stack.authoringContributions.pslBlockDescriptors, | ||
@@ -71,3 +71,2 @@ }; | ||
| composedExtensionContracts: stack.extensionContracts, | ||
| scalarTypeDescriptors: stack.scalarTypeDescriptors, | ||
| authoringContributions: stack.authoringContributions, | ||
@@ -74,0 +73,0 @@ codecLookup: stack.codecLookup, |
+2
-1
@@ -10,2 +10,4 @@ import type { AuthoringPslBlockDescriptorNamespace } from '@prisma-next/framework-components/authoring'; | ||
| * declaration, invalid qualified type) hold even without descriptors. | ||
| * `scalarTypes` is not consumed by the pipeline itself — it is the | ||
| * control-stack projection semantic tokens and completions classify against. | ||
| */ | ||
@@ -35,3 +37,2 @@ export interface PipelineInputs { | ||
| sourceFile, | ||
| scalarTypes: inputs.scalarTypes, | ||
| pslBlockDescriptors: inputs.pslBlockDescriptors, | ||
@@ -38,0 +39,0 @@ }); |
@@ -129,3 +129,2 @@ import { buildSymbolTable, type SymbolTable } from '@prisma-next/psl-parser'; | ||
| sourceFile: artifacts.sourceFile, | ||
| scalarTypes: controlStack.scalarTypes, | ||
| pslBlockDescriptors: controlStack.pslBlockDescriptors, | ||
@@ -132,0 +131,0 @@ }).table; |
@@ -38,2 +38,3 @@ import type { SymbolTable } from '@prisma-next/psl-parser'; | ||
| } from 'vscode-languageserver'; | ||
| import { refinesScalarType } from './named-type-classification'; | ||
@@ -552,9 +553,9 @@ export type SemanticTokenType = | ||
| } | ||
| if (Object.hasOwn(table.topLevel.scalars, name)) { | ||
| return { tokenType: 'type', modifierBitset: semanticTokenModifierBits.defaultLibrary }; | ||
| const namedType = table.topLevel.namedTypes[name]; | ||
| if (namedType !== undefined) { | ||
| return refinesScalarType(namedType, source.scalarTypes) | ||
| ? { tokenType: 'type', modifierBitset: semanticTokenModifierBits.defaultLibrary } | ||
| : { tokenType: 'type' }; | ||
| } | ||
| if ( | ||
| Object.hasOwn(table.topLevel.typeAliases, name) || | ||
| Object.hasOwn(table.topLevel.blocks, name) | ||
| ) { | ||
| if (Object.hasOwn(table.topLevel.blocks, name)) { | ||
| return { tokenType: 'type' }; | ||
@@ -561,0 +562,0 @@ } |
+9
-1
@@ -374,3 +374,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url'; | ||
| } | ||
| connection.console.error(error instanceof Error ? error.message : String(error)); | ||
| // The connection can die between the `disposed` check and this log call | ||
| // (e.g. the client tears down the transport before `dispose()` runs); | ||
| // `console.error` sends a notification, which then throws on the dead | ||
| // connection. Swallow it — there is nowhere left to report to. | ||
| try { | ||
| connection.console.error(error instanceof Error ? error.message : String(error)); | ||
| } catch { | ||
| // Connection already disposed; nothing to do. | ||
| } | ||
| }); | ||
@@ -377,0 +385,0 @@ } |
Sorry, the diff of this file is too big to display
300387
1.5%21
5%4017
1.01%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed