typir
Version:
General purpose type checking library
106 lines • 4.17 kB
JavaScript
/******************************************************************************
* Copyright 2024 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { assertTrue } from '../utils/utils.js';
export class DefaultTypeRelationshipCaching {
constructor(services) {
this.graph = services.infrastructure.Graph;
}
getRelationshipUnidirectional(from, to, $relation) {
return from.getOutgoingEdges($relation).find(edge => edge.to === to);
}
getRelationshipBidirectional(from, to, $relation) {
// for bidirectional edges, check outgoing and incoming edges, since the graph contains only a single edge!
return from.getEdges($relation).find(edge => edge.to === to);
}
setOrUpdateUnidirectionalRelationship(edgeToCache, edgeCaching) {
return this.setOrUpdateRelationship(edgeToCache, edgeCaching, false);
}
setOrUpdateBidirectionalRelationship(edgeToCache, edgeCaching) {
return this.setOrUpdateRelationship(edgeToCache, edgeCaching, true);
}
setOrUpdateRelationship(edgeToCache, edgeCaching, bidirectional) {
// identify the edge to store the value
const edge = bidirectional
? this.getRelationshipBidirectional(edgeToCache.from, edgeToCache.to, edgeToCache.$relation)
: this.getRelationshipUnidirectional(edgeToCache.from, edgeToCache.to, edgeToCache.$relation);
// don't cache some values (but ensure, that PENDING is overridden/updated!) => un-set the relationship
if (this.storeCachingInformation(edgeCaching) === false) {
if (edge) {
this.graph.removeEdge(edge);
}
else {
// no edge exists, no edge wanted => nothing to do
}
return undefined;
}
// handle missing edge
if (!edge) {
// reuse the given edge
this.graph.addEdge(edgeToCache);
// in case of non-directed edges, check the opposite direction as well
return edgeToCache;
}
// set/update the values of the existing edge
edge.cachingInformation = edgeCaching;
assertTrue(edge.$relation === edgeToCache.$relation);
// update data of specific edges!
// Object.assign throws an error for readonly properties => it cannot be used here!
const propertiesToIgnore = ['from', 'to', '$relation', 'cachingInformation'];
const keys = Object.keys(edgeToCache);
for (const v of keys) {
if (propertiesToIgnore.includes(v)) {
// don't update these properties
}
else {
edge[v] = edgeToCache[v];
}
}
return edge;
}
/** Override this function to store more or less relationships in the type graph. */
storeCachingInformation(value) {
return value === 'PENDING' || value === 'LINK_EXISTS';
}
}
export const CachePending = 'CACHE_PENDING';
export class DefaultLanguageNodeInferenceCaching {
constructor() {
this.initializeCache();
}
initializeCache() {
this.cache = new Map();
}
cacheSet(languageNode, type) {
this.pendingClear(languageNode);
this.cache.set(languageNode, type);
}
cacheGet(languageNode) {
if (this.pendingGet(languageNode)) {
return undefined;
}
else {
return this.cache.get(languageNode);
}
}
cacheClear() {
this.cache.clear();
}
pendingSet(languageNode) {
this.cache.set(languageNode, CachePending);
}
pendingClear(languageNode) {
if (this.cache.get(languageNode) !== CachePending) {
// do nothing
}
else {
this.cache.delete(languageNode);
}
}
pendingGet(languageNode) {
return this.cache.has(languageNode) && this.cache.get(languageNode) === CachePending;
}
}
//# sourceMappingURL=caching.js.map