UNPKG

@yellicode/elements

Version:

The meta model API for Yellicode - an extensible code generator.

103 lines (102 loc) 5.27 kB
/* * Copyright (c) 2020 Yellicode * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Prioritizes which keys should be resolved before others. For example, before resolving Element.appliedStereotypes // (where we process tagged values), we should have resolved TaggedValueSpecification.definition. var resolutionPriority = ['definition', 'appliedStereotypes']; var ElementReferenceResolver = /** @class */ (function () { function ElementReferenceResolver(modelDelegate) { this.modelDelegate = modelDelegate; /** * Contains a list of unresolved references, grouped by key (that is, the name of the * referring property). */ this.unResolvedReferencesByKey = {}; } ElementReferenceResolver.prototype.addUnResolvedReference = function (key, referrer, elementId) { var isArray = false; var collection; if (Array.isArray(elementId)) { collection = elementId; isArray = true; } else collection = [elementId]; var referencesForKey = this.unResolvedReferencesByKey[key]; if (!referencesForKey) { this.unResolvedReferencesByKey[key] = referencesForKey = { isArrayProperty: isArray, referrersByElementId: {} }; } collection.forEach(function (elementId) { var referrers = referencesForKey.referrersByElementId[elementId]; if (!referrers) referencesForKey.referrersByElementId[elementId] = referrers = []; referrers.push(referrer); }); }; ElementReferenceResolver.prototype.resolve = function () { var _this = this; Object.keys(this.unResolvedReferencesByKey) .sort(function (a, b) { return resolutionPriority.indexOf(a) - resolutionPriority.indexOf(b); }) .forEach(function (key) { var group = _this.unResolvedReferencesByKey[key]; Object.keys(group.referrersByElementId).forEach(function (elementId) { var referredElement = _this.modelDelegate.findElementById(elementId); var referrers = group.referrersByElementId[elementId]; if (!referredElement) return console.warn(referrers.length + " elements have a '" + key + "' reference with unresolvable id " + elementId + "."); referrers.forEach(function (referrer) { // console.log(`${(referrer as NamedElement).name || referrer.id} has ${key} ${elementId}. Array: ${group.isArrayProperty}`); if (group.isArrayProperty) { var array = referrer[key]; if (!array) { // ensure an array (although it should already be initialized) referrer[key] = array = []; } array.push(referredElement); } else referrer[key] = referredElement; // Apply custom logic to some relationships switch (key) { case 'general': // Even though there is a onGeneralizationAdded call in modelDelegate.createElement(), // that call doesn't have any effect without a general. _this.modelDelegate.onGeneralizationAdded(referrer); break; case 'memberEnds': _this.modelDelegate.onMemberEndAdded(referrer, referredElement); break; case 'appliedStereotypes': _this.applyStereotype(referrer, referredElement); break; } }); }); }); this.unResolvedReferencesByKey = {}; }; ElementReferenceResolver.prototype.applyStereotype = function (element, st) { if (!element.taggedValues || !element.taggedValues.length) return; var stereotypeMetaProperties = st.getAllAttributes(); // stereotypes can inherit other stereotypes stereotypeMetaProperties.forEach(function (metaProperty) { if (element.hasOwnProperty(metaProperty.name)) return; // Extend the element with the property. But determine the value first. var valueSpecification = null; var taggedValue = element.taggedValues.find(function (v) { return v.definition.id === metaProperty.id; }); if (taggedValue) { valueSpecification = taggedValue.specification; } else if (metaProperty.defaultValue) { valueSpecification = metaProperty.defaultValue; } element[metaProperty.name] = valueSpecification ? valueSpecification.getValue() : null; }); }; return ElementReferenceResolver; }()); export { ElementReferenceResolver };