greybel-languageserver-core
Version:
Core functionality of language server for GreyScript
91 lines • 4.15 kB
JavaScript
"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