autouml
Version:
Autogenerate UML diagrams using d2
222 lines (221 loc) • 7.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileMapper = void 0;
var MissingArgumentError_1 = require("./MissingArgumentError");
var TypeScraper_1 = require("./TypeScraper");
var helpers_1 = require("./helpers");
var wellknown_1 = require("./wellknown");
var FileMapper = /** @class */ (function () {
function FileMapper(tsoptions, umloptions) {
this.map = {
scopeType: 0 /* autouml.mapping.ScopeType.PROGRAM */,
name: "program",
children: [],
parent: null,
// connectors: [],
};
this.currentScope = this.map;
this.numconstructors = 0;
this.tsoptions = tsoptions;
this.umloptions = umloptions;
this.disallowNewFunctions = 0;
this.relations = new Map();
}
FileMapper.prototype.getRelationsArray = function () {
var ans = [];
this.relations.forEach(function (maps, src) {
maps.forEach(function (dests, type) {
dests.forEach(function (dst) {
ans.push({
src: JSON.parse(src),
type: type,
dst: JSON.parse(dst),
});
});
});
});
return ans;
};
FileMapper.prototype.mapFiles = function () {
var s = new TypeScraper_1.TypeScraper(this);
s.run();
return [this.map, this.getRelationsArray()];
};
FileMapper.prototype.getFiles = function () {
return this.tsoptions.fileNames;
};
FileMapper.prototype.getTSOptions = function () {
return this.tsoptions;
};
FileMapper.prototype.getUMLOptions = function () {
return this.umloptions;
};
FileMapper.prototype.getRelations = function () {
return this.relations;
};
FileMapper.prototype.getCurrentFileName = function () {
// go up the scope tree until you find one that is a file
var s = this.currentScope;
while (s.scopeType != 1 /* autouml.mapping.ScopeType.FILE */ &&
s != null) {
var p = s.parent;
if (p) {
s = p;
}
}
return s.name;
};
/**
* Prevent the adding of new scopes. This is used to deal with
* inner functions. Note that each call to preventNewScope
* mostbe accompanied by a call to allowNewScopes
*/
FileMapper.prototype.preventNewFunctions = function () {
this.disallowNewFunctions++;
};
FileMapper.prototype.allowNewFunctions = function () {
this.disallowNewFunctions--;
};
FileMapper.prototype.startScope = function (name, type, scopeITSType) {
var scope = {
scopeType: type,
name: name,
children: [],
parent: this.currentScope,
};
// TODO: very risky programming
switch (type) {
case 5 /* autouml.mapping.ScopeType.ENUM */:
scope.enumData = [];
break;
case 4 /* autouml.mapping.ScopeType.INTERFACE */:
scope.interfaceData = [];
break;
case 3 /* autouml.mapping.ScopeType.CLASS */:
scope.fields = [];
scope.methods = [];
break;
}
if (scopeIsEnumInterfaceOrClass(scope)) {
if (scopeITSType) {
scope.selfType = scopeITSType;
}
else {
throw new MissingArgumentError_1.MissingArgumentError("startScope");
}
}
this.currentScope.children.push(scope);
this.currentScope = scope;
};
FileMapper.prototype.endScope = function () {
var pscope = this.currentScope.parent;
if (pscope !== null) {
this.currentScope = pscope;
}
};
FileMapper.prototype.getMapping = function () {
return this.map;
};
FileMapper.prototype.addEnumMember = function (name) {
if (scopeIsEnum(this.currentScope)) {
this.currentScope.enumData.push(name);
}
};
FileMapper.prototype.addPropertySignature = function (name, type) {
if (scopeIsInterface(this.currentScope)) {
this.currentScope.interfaceData.push({
name: name,
type: type,
});
}
};
FileMapper.prototype.addPropertyDeclaration = function (name, access, type) {
if (scopeIsClass(this.currentScope)) {
this.currentScope.fields.push({
name: name,
type: type,
access: access,
});
}
};
FileMapper.prototype.addMethod = function (name, access, type, parameters, isConstructor) {
if (isConstructor === void 0) { isConstructor = false; }
if (this.disallowNewFunctions) {
return;
}
if (scopeIsClass(this.currentScope)) {
var obj = {
name: name,
type: type,
access: access,
parameters: parameters,
isConstructor: isConstructor,
};
if (isConstructor) {
this.currentScope.methods.splice(this.numconstructors, 0, obj);
this.numconstructors++;
}
else {
this.currentScope.methods.push(obj);
}
}
};
// add a relationship between two types
// originally intended for inheritance and implementation
FileMapper.prototype.addRelation = function (src, type, dst) {
if (dst.isPrimitive ||
src.isPrimitive ||
wellknown_1.wellKnownTypesSet.has(src.name) ||
wellknown_1.wellKnownTypesSet.has(dst.name)) {
return;
}
if (((0, helpers_1.from_node_modules)(src) ||
(0, helpers_1.from_node_modules)(dst)) &&
!this.umloptions.includeNodeModules) {
return;
}
var srckey = JSON.stringify(src);
var dststring = JSON.stringify(dst);
// create src
if (!this.relations.has(srckey)) {
this.relations.set(srckey, new Map());
}
var connDict = this.relations.get(srckey);
// create dict if needed
if (!connDict.has(type)) {
connDict.set(type, new Set());
}
var dstSet = connDict.get(type);
// add dst to hash
dstSet.add(dststring);
// check if it has parameters
for (var _i = 0, _a = dst.typeParameters; _i < _a.length; _i++) {
var p = _a[_i];
this.addRelation(src, type, p);
}
};
// add connections to the current scope
// originally designed for dependence, aggregation, composition
FileMapper.prototype.addCurrentScopeRelation = function (type, dst) {
if (scopeIsEnumInterfaceOrClass(this.currentScope)) {
this.addRelation(this.currentScope.selfType, type, dst);
}
};
return FileMapper;
}());
exports.FileMapper = FileMapper;
function scopeIsInterface(s) {
return (s.scopeType === 4 /* autouml.mapping.ScopeType.INTERFACE */);
}
function scopeIsClass(s) {
return s.scopeType === 3 /* autouml.mapping.ScopeType.CLASS */;
}
function scopeIsEnum(s) {
return s.scopeType === 5 /* autouml.mapping.ScopeType.ENUM */;
}
function scopeIsEnumInterfaceOrClass(s) {
return (s.scopeType === 3 /* autouml.mapping.ScopeType.CLASS */ ||
s.scopeType ===
4 /* autouml.mapping.ScopeType.INTERFACE */ ||
s.scopeType === 5 /* autouml.mapping.ScopeType.ENUM */);
}