UNPKG

@yellicode/elements

Version:

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

107 lines (106 loc) 5.36 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/. */ import { ElementJSONTransformer } from './element-json-transformer'; import { ElementReferenceResolver } from './element-reference-resolver'; import { ElementComparerImpl } from '../element-comparer'; import { ElementType } from '../interfaces'; var ElementVisitor = /** @class */ (function () { /** * Constructor. Creates a new ElementVisitor instance. * @param applySorting True to sort packaged- and ordered (having an Order property) elements. */ function ElementVisitor(modelDelegate, applySorting) { var referenceResolver = new ElementReferenceResolver(modelDelegate); this.jsonTransformer = new ElementJSONTransformer(referenceResolver, applySorting ? ElementComparerImpl.getInstance() : null); this.modelDelegate = modelDelegate; } ElementVisitor.prototype.visit = function (root) { var target = this.visitRecursive(root, null, 0); this.jsonTransformer.resolveReferences(); return target; }; ElementVisitor.prototype.visitRecursive = function (source, owner, depth) { var _this = this; var elementType = source['elementType'] || null; // <debug stuff> // let consoleIndent = ' '; // for (let i = 0; i < depth; i++) consoleIndent += ' '; // console.log(`${consoleIndent}+ Creating new ${elementType || 'object'} (owner: ${ElementVisitor.getConsoleDisplayName(owner)}).`); // </debug stuff> var target; if (elementType) { var elementId = source['id'] || null; // the id is not required for all element types, but it is important when it is. target = this.modelDelegate.createElement(elementType, owner, { id: elementId }, null); } else { target = source; } // <debug stuff> // const debugName = ElementVisitor.getConsoleDisplayName(target); // </debug stuff> Object.keys(source).forEach(function (k) { var value = source[k]; if (typeof (value) !== 'object') { if (k === 'id' || k === 'elementType') return; // we already have these var mappedValue = _this.jsonTransformer.fromJSON(target, k, value); if (mappedValue) { // console.log(`${consoleIndent}${debugName}.${k} = '${mappedValue}'.`); target[k] = mappedValue; } // else console.log(`${consoleIndent}${debugName}.${k} was not mapped (yet)'.`); return; } // The value is an object (or an array). if (Array.isArray(value)) { if (!target[k]) { console.warn("Target " + ElementVisitor.getConsoleDisplayName(target) + " has no array member with key '" + k + "'."); return; } if (!value.length) return; var isObjectArray = typeof (value[0]) === 'object'; if (isObjectArray) { for (var index = 0, len = value.length; index < len; index++) { var element = value[index]; // console.log(`${consoleIndent}Visiting ${debugName}.${k}[${index}] =>`); var childResult = _this.visitRecursive(element, elementType ? target : null, depth + 1); // console.log(`${consoleIndent}${debugName}.${k}[${index}] = '${ElementVisitor.getConsoleDisplayName(childResult)}'.`); target[k][index] = childResult; } } else { // Do not visit the non-object array, just map the value var mappedValue = _this.jsonTransformer.fromJSON(target, k, value); if (mappedValue) { // console.log(`${consoleIndent}${debugName}.${k} = '${mappedValue}'.`); target[k] = mappedValue; } // else console.log(`${consoleIndent}${debugName}.${k} was not mapped (yet)'.`); } } else { // The value is a child object // console.log(`${consoleIndent}Visiting ${debugName}.${k} =>`); var childResult = _this.visitRecursive(value, elementType ? target : null, depth + 1); // console.log(`${consoleIndent}${debugName}.${k} = '${ElementVisitor.getConsoleDisplayName(childResult)}'.`); target[k] = childResult; } }); return target; }; ElementVisitor.getConsoleDisplayName = function (target) { if (!target) return 'none'; if (!target.hasOwnProperty('elementType')) return '{}'; return (target.name || ElementType[target.elementType]); }; return ElementVisitor; }()); export { ElementVisitor };