UNPKG

greybel-languageserver-core

Version:
95 lines 4.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DocumentWorkspaceMerger = exports.DocumentWorkspaceMergerJob = void 0; const fast_toposort_1 = require("fast-toposort"); const type_manager_1 = require("../type-manager"); const document_workspace_builder_1 = require("../document-manager/document-workspace-builder"); class DocumentWorkspaceMergerJob { constructor(cache) { this.cache = cache; } getTypeDocument(documentUri, context) { const activeDocument = context.getRef(documentUri); // collect imports with namespace if possible if (activeDocument != null) { const namespacesOfImports = (0, type_manager_1.aggregateImportsWithNamespaceFromLocations)(context.getDependencies(documentUri), context.getRefMap()); if (namespacesOfImports.length === 0) { return activeDocument.typeDocument; } const mergedTypeDoc = activeDocument.typeDocument.merge(...namespacesOfImports.map((it) => { return { document: it.typeDoc, namespaces: [{ exportFrom: 'module.exports', namespace: it.namespace }] }; })); return mergedTypeDoc; } return activeDocument.typeDocument; } getExternalTypeDocumentsRelatedToDocument(document, context) { const documentUri = document.textDocument.uri; const documentUris = context.documents.map((item) => item.textDocument.uri); // sort by it's usage const documentGraph = context.documents.map((item) => { const depUris = context.getDependencies(item.textDocument.uri); return depUris.map((dep) => { return [item.textDocument.uri, dep.location]; }); }); const topoSorted = (0, fast_toposort_1.toposort)(documentUris, documentGraph.flat()); const externalTypeDocs = new Array(topoSorted.length); for (let index = topoSorted.length - 1; index >= 0; index--) { const itemUri = topoSorted[index]; if (itemUri === documentUri) continue; const itemTypeDoc = this.getTypeDocument(itemUri, context); if (itemTypeDoc == null) continue; externalTypeDocs[index] = itemTypeDoc; } const availableExternalTypeDocs = externalTypeDocs.filter((item) => item != null); return availableExternalTypeDocs; } async process(document, context) { const documentUri = document.textDocument.uri; const cacheKey = this.cache.createCacheKey(document, context.documents); if (this.cache.typeDocuments.has(cacheKey)) { return this.cache.typeDocuments.get(cacheKey); } this.cache.registerCacheKey(cacheKey, documentUri); await context.loadDependencies(); const externalTypeDocs = this.getExternalTypeDocumentsRelatedToDocument(document, context); // collect imports with namespace const namespacesOfImports = (0, type_manager_1.aggregateImportsWithNamespaceFromLocations)(context.getDependencies(documentUri), context.getRefMap()); const mergedTypeDoc = document.typeDocument.merge(...namespacesOfImports.map((it) => { return { document: it.typeDoc, namespaces: [{ exportFrom: 'module.exports', namespace: it.namespace }] }; }), ...externalTypeDocs.map((it) => { return { document: it }; })); this.cache.typeDocuments.set(cacheKey, mergedTypeDoc); return mergedTypeDoc; } } exports.DocumentWorkspaceMergerJob = DocumentWorkspaceMergerJob; class DocumentWorkspaceMerger { constructor(cache) { this.cache = cache; this.pendingJobs = new Map(); } async process(document, context) { const workspaceBuilder = new document_workspace_builder_1.DocumentWorkspaceBuilder({ context }); const workspaceContext = await workspaceBuilder.build(); const job = new DocumentWorkspaceMergerJob(this.cache); return job.process(document, workspaceContext); } async build(document, context) { const existingJob = this.pendingJobs.get(document.textDocument.uri); if (existingJob) { return existingJob; } const job = this.process(document, context); this.pendingJobs.set(document.textDocument.uri, job); const result = await job; this.pendingJobs.delete(document.textDocument.uri); return result; } } exports.DocumentWorkspaceMerger = DocumentWorkspaceMerger; //# sourceMappingURL=document-workspace-merger.js.map