UNPKG

greybel-languageserver-core

Version:
91 lines 4.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DocumentDependencyMerger = exports.DocumentDependencyMergerJob = void 0; const types_1 = require("../../types"); const document_graph_builder_1 = require("../document-manager/document-graph-builder"); const type_manager_1 = require("../type-manager"); class DocumentDependencyMergerJob { constructor(cache) { this.cache = cache; this.refs = new Map(); } mergeDocuments(node, externalTypeDocs) { const namespacesOfImports = (0, type_manager_1.aggregateImportsWithNamespaceFromGraph)(node, this.refs); const activeDocument = node.item.document; if (namespacesOfImports.length === 0) { return activeDocument.typeDocument.merge(...externalTypeDocs.map((it) => { return { document: it }; })); } return activeDocument.typeDocument.merge(...namespacesOfImports.map((it) => { return { document: it.typeDoc, namespaces: [{ exportFrom: 'module.exports', namespace: it.namespace }] }; }), ...externalTypeDocs.map((it) => { return { document: it }; })); } process(node, context) { const activeDocument = node.item.document; const documentUri = activeDocument.textDocument.uri; const existingRef = this.refs.get(documentUri); if (existingRef !== undefined) { return existingRef; } this.refs.set(documentUri, null); const externalTypeDocs = []; const cacheKey = this.cache.createCacheKey(activeDocument, (0, types_1.getAllDependencyLocationsFromGraph)(node, new Set(activeDocument.textDocument.uri))); if (this.cache.typeDocuments.has(cacheKey)) { const cachedTypeDoc = this.cache.typeDocuments.get(cacheKey); this.refs.set(documentUri, cachedTypeDoc); return cachedTypeDoc; } this.cache.registerCacheKey(cacheKey, documentUri); if (node.children.length === 0) { this.refs.set(documentUri, activeDocument.typeDocument); this.cache.typeDocuments.set(cacheKey, activeDocument.typeDocument); return activeDocument.typeDocument; } for (let index = 0; index < node.children.length; index++) { const child = node.children[index]; const itemTypeDoc = this.process(child, context); // Skip namespace imports to be added to externalTypeDocs, process needs to be called anyway though to ensure availability of the type document if (child.item.location.type === types_1.DependencyType.Import) continue; if (itemTypeDoc === null) return; externalTypeDocs.push(itemTypeDoc); } const mergedTypeDoc = this.mergeDocuments(node, externalTypeDocs); this.refs.set(documentUri, mergedTypeDoc); this.cache.typeDocuments.set(cacheKey, mergedTypeDoc); return mergedTypeDoc; } } exports.DocumentDependencyMergerJob = DocumentDependencyMergerJob; class DocumentDependencyMerger { constructor(cache) { this.cache = cache; this.pendingJobs = new Map(); } async process(document, context) { const graphBuilder = new document_graph_builder_1.DocumentGraphBuilder({ documentManager: context.documentManager, entrypoint: document }); const rootNode = await graphBuilder.build(); const job = new DocumentDependencyMergerJob(this.cache); return job.process(rootNode, context); } 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.DocumentDependencyMerger = DocumentDependencyMerger; //# sourceMappingURL=document-dependency-merger.js.map