"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createLanguageService = void 0; const language_core_1 = require("@volar/language-core"); const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument"); const documents_1 = require("./documents"); const autoInsert = require("./languageFeatures/autoInsert"); const callHierarchy = require("./languageFeatures/callHierarchy"); const codeActionResolve = require("./languageFeatures/codeActionResolve"); const codeActions = require("./languageFeatures/codeActions"); const codeLens = require("./languageFeatures/codeLens"); const codeLensResolve = require("./languageFeatures/codeLensResolve"); const completions = require("./languageFeatures/complete"); const completionResolve = require("./languageFeatures/completeResolve"); const definition = require("./languageFeatures/definition"); const documentHighlight = require("./languageFeatures/documentHighlights"); const documentLink = require("./languageFeatures/documentLinks"); const documentLinkResolve = require("./languageFeatures/documentLinkResolve"); const semanticTokens = require("./languageFeatures/documentSemanticTokens"); const fileReferences = require("./languageFeatures/fileReferences"); const fileRename = require("./languageFeatures/fileRename"); const hover = require("./languageFeatures/hover"); const inlayHints = require("./languageFeatures/inlayHints"); const inlayHintResolve = require("./languageFeatures/inlayHintResolve"); const references = require("./languageFeatures/references"); const rename = require("./languageFeatures/rename"); const renamePrepare = require("./languageFeatures/renamePrepare"); const signatureHelp = require("./languageFeatures/signatureHelp"); const diagnostics = require("./languageFeatures/validation"); const workspaceSymbol = require("./languageFeatures/workspaceSymbols"); const colorPresentations = require("./documentFeatures/colorPresentations"); const documentColors = require("./documentFeatures/documentColors"); const documentSymbols = require("./documentFeatures/documentSymbols"); const foldingRanges = require("./documentFeatures/foldingRanges"); const format = require("./documentFeatures/format"); const linkedEditingRanges = require("./documentFeatures/linkedEditingRanges"); const selectionRanges = require("./documentFeatures/selectionRanges"); const common_1 = require("./utils/common"); function createLanguageService(modules, env, config, languageHost) { if (languageHost.workspacePath.indexOf('\\') >= 0 || languageHost.rootPath.indexOf('\\') >= 0) { throw new Error('Volar: Current directory must be posix style.'); } if (languageHost.getScriptFileNames().some(fileName => fileName.indexOf('\\') >= 0)) { throw new Error('Volar: Script file names must be posix style.'); } const languageContext = (0, language_core_1.createLanguageContext)(languageHost, Object.values(config.languages ?? {}).filter(common_1.notEmpty)); const context = createLanguageServicePluginContext(modules, env, config, languageHost, languageContext); return createLanguageServiceBase(context); } exports.createLanguageService = createLanguageService; function createLanguageServicePluginContext(modules, env, config, host, languageContext) { const textDocumentMapper = (0, documents_1.createDocumentsAndSourceMaps)(env, host, languageContext.virtualFiles); const documents = new WeakMap(); const documentVersions = new Map(); const context = { ...languageContext, env, inject: (key, ...args) => { for (const service of Object.values(context.services)) { const provide = service.provide?.[key]; if (provide) { return provide(...args); } } throw `No service provide ${key}`; }, rules: config.rules ?? {}, services: {}, documents: textDocumentMapper, commands: { rename: { create(uri, position) { const source = toSourceLocation(uri, position, data => typeof data.rename === 'object' ? !!data.rename.normalize : !!data.rename); if (!source) { return; } return { title: '', command: 'editor.action.rename', arguments: [ source.uri, source.position, ], }; }, is(command) { return command.command === 'editor.action.rename'; }, }, showReferences: { create(uri, position, locations) { const source = toSourceLocation(uri, position); if (!source) { return; } const sourceReferences = []; for (const reference of locations) { if (context.documents.isVirtualFileUri(reference.uri)) { for (const [_, map] of context.documents.getMapsByVirtualFileUri(reference.uri)) { const range = map.toSourceRange(reference.range); if (range) { sourceReferences.push({ uri: map.sourceFileDocument.uri, range }); } } } else { sourceReferences.push(reference); } } return { title: locations.length === 1 ? '1 reference' : `${locations.length} references`, command: 'editor.action.showReferences', arguments: [ source.uri, source.position, sourceReferences, ], }; }, is(command) { return command.command === 'editor.action.showReferences'; }, }, setSelection: { create(position) { return { title: '', command: 'setSelection', arguments: [{ selection: { selectionStartLineNumber: position.line + 1, positionLineNumber: position.line + 1, selectionStartColumn: position.character + 1, positionColumn: position.character + 1, }, }], }; }, is(command) { return command.command === 'setSelection'; } }, }, getTextDocument, }; for (const serviceId in config.services ?? {}) { const service = config.services?.[serviceId]; if (service) { context.services[serviceId] = service(context, modules); } } return context; function toSourceLocation(uri, position, filter) { if (!textDocumentMapper.isVirtualFileUri(uri)) { return { uri, position }; } const map = textDocumentMapper.getVirtualFileByUri(uri); if (map) { for (const [_, map] of context.documents.getMapsByVirtualFileUri(uri)) { const sourcePosition = map.toSourcePosition(position, filter); if (sourcePosition) { return { uri: map.sourceFileDocument.uri, position: sourcePosition, }; } } } } function getTextDocument(uri) { for (const [_, map] of context.documents.getMapsByVirtualFileUri(uri)) { return map.virtualFileDocument; } const fileName = env.uriToFileName(uri); const scriptSnapshot = host.getScriptSnapshot(fileName); if (scriptSnapshot) { let document = documents.get(scriptSnapshot); if (!document) { const newVersion = (documentVersions.get(uri.toLowerCase()) ?? 0) + 1; documentVersions.set(uri.toLowerCase(), newVersion); document = vscode_languageserver_textdocument_1.TextDocument.create(uri, host.getLanguageId?.(fileName) ?? (0, common_1.resolveCommonLanguageId)(uri), newVersion, scriptSnapshot.getText(0, scriptSnapshot.getLength())); documents.set(scriptSnapshot, document); } return document; } } } function createLanguageServiceBase(context) { return { getTriggerCharacters: () => Object.values(context.services).map(service => service?.triggerCharacters ?? []).flat(), getAutoFormatTriggerCharacters: () => Object.values(context.services).map(service => service?.autoFormatTriggerCharacters ?? []).flat(), getSignatureHelpTriggerCharacters: () => Object.values(context.services).map(service => service?.signatureHelpTriggerCharacters ?? []).flat(), getSignatureHelpRetriggerCharacters: () => Object.values(context.services).map(service => service?.signatureHelpRetriggerCharacters ?? []).flat(), format: format.register(context), getFoldingRanges: foldingRanges.register(context), getSelectionRanges: selectionRanges.register(context), findLinkedEditingRanges: linkedEditingRanges.register(context), findDocumentSymbols: documentSymbols.register(context), findDocumentColors: documentColors.register(context), getColorPresentations: colorPresentations.register(context), doValidation: diagnostics.register(context), findReferences: references.register(context), findFileReferences: fileReferences.register(context), findDefinition: definition.register(context, 'provideDefinition', data => !!data.definition, data => !!data.definition), findTypeDefinition: definition.register(context, 'provideTypeDefinition', data => !!data.definition, data => !!data.definition), findImplementations: definition.register(context, 'provideImplementation', data => !!data.references, () => false), prepareRename: renamePrepare.register(context), doRename: rename.register(context), getEditsForFileRename: fileRename.register(context), getSemanticTokens: semanticTokens.register(context), doHover: hover.register(context), doComplete: completions.register(context), doCodeActions: codeActions.register(context), doCodeActionResolve: codeActionResolve.register(context), doCompletionResolve: completionResolve.register(context), getSignatureHelp: signatureHelp.register(context), doCodeLens: codeLens.register(context), doCodeLensResolve: codeLensResolve.register(context), findDocumentHighlights: documentHighlight.register(context), findDocumentLinks: documentLink.register(context), doDocumentLinkResolve: documentLinkResolve.register(context), findWorkspaceSymbols: workspaceSymbol.register(context), doAutoInsert: autoInsert.register(context), getInlayHints: inlayHints.register(context), doInlayHintResolve: inlayHintResolve.register(context), callHierarchy: callHierarchy.register(context), dispose: () => Object.values(context.services).forEach(service => service.dispose?.()), context, }; } //# sourceMappingURL=baseLanguageService.js.map