@yellicode/elements
Version:
The meta model API for Yellicode - an extensible code generator.
107 lines (106 loc) • 5.36 kB
JavaScript
/*
* 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 };