UNPKG

@prisma/language-server

Version:
225 lines • 10.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleDiagnosticsRequest = handleDiagnosticsRequest; exports.handleDefinitionRequest = handleDefinitionRequest; exports.handleDocumentFormatting = handleDocumentFormatting; exports.handleHoverRequest = handleHoverRequest; exports.handleCompletionRequest = handleCompletionRequest; exports.handleReferencesRequest = handleReferencesRequest; exports.handleRenameRequest = handleRenameRequest; exports.handleCompletionResolveRequest = handleCompletionResolveRequest; exports.handleCodeActions = handleCodeActions; exports.handleDocumentSymbol = handleDocumentSymbol; const vscode_languageserver_1 = require("vscode-languageserver"); const format_1 = __importDefault(require("./prisma-schema-wasm/format")); const lint_1 = __importDefault(require("./prisma-schema-wasm/lint")); const code_actions_1 = require("./code-actions"); const rename_1 = require("./code-actions/rename"); const validations_1 = require("./validations"); const ast_1 = require("./ast"); const completions_1 = require("./completions"); const Schema_1 = require("./Schema"); const DiagnosticMap_1 = require("./DiagnosticMap"); const references_1 = __importDefault(require("./prisma-schema-wasm/references")); const hover_1 = __importDefault(require("./prisma-schema-wasm/hover")); function handleDiagnosticsRequest(schema, onError) { const res = (0, lint_1.default)(schema, (errorMessage) => { if (onError) { onError(errorMessage); } }); const diagnostics = new DiagnosticMap_1.DiagnosticMap(schema.documents.map((doc) => doc.uri)); if (res.some((diagnostic) => diagnostic.text === "Field declarations don't require a `:`." || diagnostic.text === 'Model declarations have to be indicated with the `model` keyword.')) { if (onError) { onError("You might currently be viewing a Prisma 1 datamodel which is based on the GraphQL syntax. The current Prisma Language Server doesn't support this syntax. If you are handling a Prisma 1 datamodel, please change the file extension to `.graphql` so the new Prisma Language Server does not get triggered anymore."); } } for (const diag of res) { const previewNotKnownRegex = /The preview feature \"[a-zA-Z]+\" is not known/; const uri = diag.file_name; const document = schema.findDocByUri(uri); if (!document) { continue; } const diagnostic = { range: { start: document.positionAt(diag.start), end: document.positionAt(diag.end), }, message: previewNotKnownRegex.test(diag.text) ? `${diag.text}.\nIf this is unexpected, it might be due to your editor's Prisma Extension being out of date.` : diag.text, source: 'Prisma', }; if (diag.is_warning) { diagnostic.severity = vscode_languageserver_1.DiagnosticSeverity.Warning; } else { diagnostic.severity = vscode_languageserver_1.DiagnosticSeverity.Error; } diagnostics.add(uri, diagnostic); } (0, validations_1.validateIgnoredBlocks)(schema, diagnostics); return diagnostics; } /** * @todo Use official schema.prisma parser. This is a workaround! */ function handleDefinitionRequest(schema, initiatingDocument, params) { const position = params.position; const word = (0, ast_1.getWordAtPosition)(initiatingDocument, position); if (word === '') { return; } // get start position of block const results = schema .linesAsArray() .map(({ document, lineIndex, text }) => { if ((text.includes('model') && text.includes(word)) || (text.includes('type') && text.includes(word)) || (text.includes('enum') && text.includes(word))) { return [document, lineIndex]; } }) .filter((result) => result !== undefined); if (results.length === 0) { return; } const foundBlocks = results .map(([document, lineNo]) => { const block = (0, ast_1.getBlockAtPosition)(document.uri, lineNo, schema); if (block && block.name === word && block.range.start.line === lineNo) { return block; } }) .filter((block) => block !== undefined); if (foundBlocks.length !== 1) { return; } if (!foundBlocks[0]) { return; } return [ { targetUri: foundBlocks[0].definingDocument.uri, targetRange: foundBlocks[0].range, targetSelectionRange: foundBlocks[0].nameRange, }, ]; } /** * This handler provides the modification to the document to be formatted. */ function handleDocumentFormatting(schema, initiatingDocument, params, onError) { const formatted = (0, format_1.default)(schema, initiatingDocument, params, onError); return [vscode_languageserver_1.TextEdit.replace((0, ast_1.fullDocumentRange)(initiatingDocument), formatted)]; } function handleHoverRequest(schema, initiatingDocument, params, onError) { return (0, hover_1.default)(schema, initiatingDocument, params, onError); } /** * * This handler provides the initial list of the completion items. */ function handleCompletionRequest(schema, document, params, onError) { return (0, completions_1.prismaSchemaWasmCompletions)(schema, params, onError) || (0, completions_1.localCompletions)(schema, document, params, onError); } function handleReferencesRequest(schema, params, onError) { return (0, references_1.default)(schema, params, onError); } function handleRenameRequest(schema, initiatingDocument, params) { const schemaLines = schema.linesAsArray(); const position = params.position; const block = (0, ast_1.getBlockAtPosition)(initiatingDocument.uri, position.line, schema); if (!block) { return undefined; } const currentLine = block.definingDocument.lines[params.position.line].text; const isDatamodelBlockRename = (0, rename_1.isDatamodelBlockName)(position, block, schema, initiatingDocument); const isMappable = ['model', 'enum', 'view'].includes(block.type); const needsMap = !isDatamodelBlockRename ? true : isMappable; const isEnumValueRename = (0, rename_1.isEnumValue)(currentLine, params.position, block, initiatingDocument); const isValidFieldRename = (0, rename_1.isValidFieldName)(currentLine, params.position, block, initiatingDocument); const isRelationFieldRename = isValidFieldRename && (0, rename_1.isRelationField)(currentLine, schema); if (isDatamodelBlockRename || isEnumValueRename || isValidFieldRename) { const edits = []; const currentName = (0, rename_1.extractCurrentName)(currentLine, isDatamodelBlockRename, isEnumValueRename, isValidFieldRename, initiatingDocument, params.position); let lineNumberOfDefinition = position.line; let blockOfDefinition = block; let lineOfDefinitionContent = currentLine; if (isDatamodelBlockRename) { // get definition of model or enum const matchBlockBeginning = new RegExp(`\\s*(${block.type})\\s+(${currentName})\\s*({)`, 'g'); const lineOfDefinition = schemaLines.find((line) => matchBlockBeginning.test(line.text)); if (!lineOfDefinition) { return; } const { document: definitionDoc, lineIndex, text } = lineOfDefinition; lineNumberOfDefinition = lineIndex; lineOfDefinitionContent = text; const definitionBlockAtPosition = (0, ast_1.getBlockAtPosition)(definitionDoc.uri, lineNumberOfDefinition, schema); if (!definitionBlockAtPosition) { return; } blockOfDefinition = definitionBlockAtPosition; } // rename marked string edits.push((0, rename_1.insertBasicRename)(params.newName, currentName, initiatingDocument, lineNumberOfDefinition)); // check if map exists already if (!isRelationFieldRename && !(0, rename_1.mapExistsAlready)(lineOfDefinitionContent, schema, blockOfDefinition, isDatamodelBlockRename) && needsMap) { // add map attribute edits.push((0, rename_1.insertMapAttribute)(currentName, position, blockOfDefinition, isDatamodelBlockRename)); } // rename references if (isDatamodelBlockRename) { edits.push((0, rename_1.renameReferencesForModelName)(currentName, params.newName, schema)); } else if (isEnumValueRename) { edits.push((0, rename_1.renameReferencesForEnumValue)(currentName, params.newName, schema, blockOfDefinition.name)); } else if (isValidFieldRename) { edits.push((0, rename_1.renameReferencesForFieldName)(currentName, params.newName, schema, blockOfDefinition, isRelationFieldRename)); } (0, rename_1.printLogMessage)(currentName, params.newName, isDatamodelBlockRename, isValidFieldRename, isEnumValueRename, block.type); return { changes: (0, rename_1.mergeEditMaps)(edits), }; } return; } /** * * @param item This handler resolves additional information for the item selected in the completion list. */ function handleCompletionResolveRequest(item) { return item; } function handleCodeActions(schema, initiatingDocument, params, onError) { if (!params.context.diagnostics.length) { return []; } return (0, code_actions_1.quickFix)(schema, initiatingDocument, params, onError); } function handleDocumentSymbol(params, document) { const schema = Schema_1.PrismaSchema.singleFile(document); return Array.from((0, ast_1.getBlocks)(schema), (block) => ({ kind: { model: vscode_languageserver_1.SymbolKind.Class, enum: vscode_languageserver_1.SymbolKind.Enum, type: vscode_languageserver_1.SymbolKind.Interface, view: vscode_languageserver_1.SymbolKind.Class, datasource: vscode_languageserver_1.SymbolKind.Struct, generator: vscode_languageserver_1.SymbolKind.Function, }[block.type], name: block.name, range: block.range, selectionRange: block.nameRange, })); } //# sourceMappingURL=MessageHandler.js.map