UNPKG

@jqassistant/ts-lce

Version:

Tool to extract language concepts from a TypeScript codebase and export them to a JSON file.

138 lines (137 loc) 4.76 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LCENamedConcept = exports.LCEConcept = void 0; exports.isNamedConcept = isNamedConcept; exports.mergeConceptMaps = mergeConceptMaps; exports.unifyConceptMap = unifyConceptMap; exports.singleEntryConceptMap = singleEntryConceptMap; exports.createConceptMap = createConceptMap; exports.getAndCastConcepts = getAndCastConcepts; const context_1 = require("./context"); /** * Base class for all language concepts. */ class LCEConcept { /** * Unique identifier for a concept class. * Should be set by subclasses. */ static conceptId; /** * Contains metadata that may be used by Processors further up the AST, or by Post-Processors. * NOTE: metadata should not be used in the toJSON method, as Concept classes should not contain any processing logic. */ metadata = new Map(); /** * Returns a JSON object that contains all the information that should be present in the JSON report that is used for graph generation. * NOTE: This method should not contain any processing logic! * * Returns all fields, except metadata by default. Also calls toJSON for all fields that are concepts, or concept arrays. */ toJSON() { const jsonObject = {}; Object.entries(this).forEach(([key, value]) => { if (value instanceof LCEConcept) { jsonObject[key] = value.toJSON(); } else if (Array.isArray(value) && value.every(item => item instanceof LCEConcept)) { jsonObject[key] = value.map(item => item.toJSON()); } else if (key === "fqn" && value instanceof context_1.FQN) { jsonObject["globalFqn"] = value.globalFqn; jsonObject["localFqn"] = value.localFqn; } else if (key !== 'metadata') { jsonObject[key] = value; } }); return jsonObject; } ; } exports.LCEConcept = LCEConcept; /** * Base class for all language concepts that can be referred to by a fully qualified name. */ class LCENamedConcept extends LCEConcept { fqn; constructor(fqn) { super(); this.fqn = fqn; } } exports.LCENamedConcept = LCENamedConcept; function isNamedConcept(concept) { return "globalFqn" in concept && "localFqn" in concept; } /** * Merges the given ConceptMaps. Array values of the same keys are concatenated. * The original maps are not modified. */ function mergeConceptMaps(...maps) { const result = new Map(); for (const map of maps) { for (const [kO, vMap] of map.entries()) { const outerRes = result.get(kO); if (!outerRes) { result.set(kO, new Map(vMap)); continue; } for (const [kI, vArr] of vMap.entries()) { const innerRes = outerRes.get(kI); if (innerRes) { outerRes.set(kI, innerRes.concat(vArr)); } else { outerRes.set(kI, [...vArr]); } } } } return result; } /** * Takes all concepts and their conceptIds and unifies them under a single outer common key. * The original map is not modified. * @returns a new ConceptMap with a single key which maps to all concepts contained in the original map */ function unifyConceptMap(conceptMap, commonKey) { const result = new Map(); let innerMap = undefined; for (const [, vMap] of conceptMap.entries()) { if (innerMap) { for (const [kI, vArr] of vMap.entries()) { const innerRes = innerMap.get(kI); if (innerRes) { innerMap.set(kI, innerRes.concat(vArr)); } else { innerMap.set(kI, [...vArr]); } } } else { innerMap = new Map(vMap); result.set(commonKey, innerMap); } } return result; } /** * creates a ConceptMap containing a single concept */ function singleEntryConceptMap(conceptId, concept, parentPropName = "") { return createConceptMap(conceptId, [concept], parentPropName); } /** * creates a ConceptMap containing a list of concepts of one concept type for a single parent property */ function createConceptMap(conceptId, concepts, parentPropName = "") { return new Map([[parentPropName, new Map([[conceptId, concepts]])]]); } /** * retrieves an array of concepts from a ConceptMap entry and casts it to the provided type */ function getAndCastConcepts(conceptId, concepts) { return concepts.has(conceptId) ? concepts.get(conceptId) : []; }