sol2uml 2.1.6 → 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/lib/associations.d.ts +1 -1
- package/lib/associations.js +11 -4
- package/lib/converterAST2Classes.js +48 -10
- package/lib/converterClass2Dot.d.ts +3 -0
- package/lib/converterClass2Dot.js +19 -8
- package/lib/converterClasses2Dot.js +4 -2
- package/lib/converterClasses2Storage.js +14 -10
- package/lib/parserFiles.js +6 -1
- package/lib/sol2uml.js +7 -0
- package/lib/umlClass.d.ts +2 -1
- package/lib/umlClass.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -97,6 +97,9 @@ Options:
|
|
|
97
97
|
-hv, --hideVariables hide variables from contracts, interfaces, structs and enums (default: false)
|
|
98
98
|
-hf, --hideFunctions hide functions from contracts, interfaces and libraries (default: false)
|
|
99
99
|
-hp, --hidePrivates hide private and internal attributes and operators (default: false)
|
|
100
|
+
-hm, --hideModifiers hide modifier functions from contracts (default: false)
|
|
101
|
+
-ht, --hideEvents hide events from contracts, interfaces and libraries (default: false)
|
|
102
|
+
-hc, --hideConstants hide file level constants (default: false)
|
|
100
103
|
-he, --hideEnums hide enum types (default: false)
|
|
101
104
|
-hs, --hideStructs hide data structures (default: false)
|
|
102
105
|
-hl, --hideLibraries hide libraries (default: false)
|
package/lib/associations.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Association, UmlClass } from './umlClass';
|
|
2
|
-
export declare const findAssociatedClass: (association: Association, sourceUmlClass: UmlClass, umlClasses: UmlClass[]) => UmlClass | undefined;
|
|
2
|
+
export declare const findAssociatedClass: (association: Association, sourceUmlClass: UmlClass, umlClasses: UmlClass[], searchedAbsolutePaths?: string[]) => UmlClass | undefined;
|
package/lib/associations.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.findAssociatedClass = void 0;
|
|
4
4
|
const umlClass_1 = require("./umlClass");
|
|
5
5
|
// Find the UML class linked to the association
|
|
6
|
-
const findAssociatedClass = (association, sourceUmlClass, umlClasses) => {
|
|
6
|
+
const findAssociatedClass = (association, sourceUmlClass, umlClasses, searchedAbsolutePaths = []) => {
|
|
7
7
|
let umlClass = umlClasses.find((targetUmlClass) => {
|
|
8
8
|
// is the source class link via the association to the target class?
|
|
9
9
|
if (isAssociated(association, sourceUmlClass, targetUmlClass))
|
|
@@ -28,7 +28,9 @@ const findAssociatedClass = (association, sourceUmlClass, umlClasses) => {
|
|
|
28
28
|
if (umlClass)
|
|
29
29
|
return umlClass;
|
|
30
30
|
// Could not find a link so now need to recursively look at imports of imports
|
|
31
|
-
|
|
31
|
+
// add to already recursively processed files to avoid getting stuck in circular imports
|
|
32
|
+
searchedAbsolutePaths.push(sourceUmlClass.absolutePath);
|
|
33
|
+
return findImplicitImport(association, sourceUmlClass, umlClasses, searchedAbsolutePaths);
|
|
32
34
|
};
|
|
33
35
|
exports.findAssociatedClass = findAssociatedClass;
|
|
34
36
|
// Tests if source class can be linked to the target class via an association
|
|
@@ -54,7 +56,7 @@ const isAssociated = (association, sourceUmlClass, targetUmlClass) => {
|
|
|
54
56
|
importedClass.alias &&
|
|
55
57
|
importedClass.className === targetUmlClass.name))));
|
|
56
58
|
};
|
|
57
|
-
const findImplicitImport = (association, sourceUmlClass, umlClasses) => {
|
|
59
|
+
const findImplicitImport = (association, sourceUmlClass, umlClasses, searchedRelativePaths) => {
|
|
58
60
|
// Get all implicit imports. That is, imports that do not explicitly import contracts or interfaces.
|
|
59
61
|
const implicitImports = sourceUmlClass.imports.filter((i) => i.classNames.length === 0);
|
|
60
62
|
// For each implicit import
|
|
@@ -65,8 +67,13 @@ const findImplicitImport = (association, sourceUmlClass, umlClasses) => {
|
|
|
65
67
|
// Could not find a class in the import file so just move onto the next loop
|
|
66
68
|
continue;
|
|
67
69
|
}
|
|
70
|
+
// Avoid circular imports
|
|
71
|
+
if (searchedRelativePaths.includes(newSourceUmlClass.absolutePath)) {
|
|
72
|
+
// Have already recursively looked for imports of imports in this file
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
68
75
|
// TODO need to handle imports that use aliases as the association will not be found
|
|
69
|
-
const umlClass = (0, exports.findAssociatedClass)(association, newSourceUmlClass, umlClasses);
|
|
76
|
+
const umlClass = (0, exports.findAssociatedClass)(association, newSourceUmlClass, umlClasses, searchedRelativePaths);
|
|
70
77
|
if (umlClass)
|
|
71
78
|
return umlClass;
|
|
72
79
|
}
|
|
@@ -48,7 +48,7 @@ function convertAST2UmlClasses(node, relativePath, filesystem = false) {
|
|
|
48
48
|
umlClasses.push(umlClass);
|
|
49
49
|
}
|
|
50
50
|
else if (childNode.type === 'StructDefinition') {
|
|
51
|
-
debug(`Adding struct ${childNode.name}`);
|
|
51
|
+
debug(`Adding file level struct ${childNode.name}`);
|
|
52
52
|
let umlClass = new umlClass_1.UmlClass({
|
|
53
53
|
name: childNode.name,
|
|
54
54
|
stereotype: umlClass_1.ClassStereotype.Struct,
|
|
@@ -62,7 +62,7 @@ function convertAST2UmlClasses(node, relativePath, filesystem = false) {
|
|
|
62
62
|
umlClasses.push(umlClass);
|
|
63
63
|
}
|
|
64
64
|
else if (childNode.type === 'EnumDefinition') {
|
|
65
|
-
debug(`Adding enum ${childNode.name}`);
|
|
65
|
+
debug(`Adding file level enum ${childNode.name}`);
|
|
66
66
|
let umlClass = new umlClass_1.UmlClass({
|
|
67
67
|
name: childNode.name,
|
|
68
68
|
stereotype: umlClass_1.ClassStereotype.Enum,
|
|
@@ -123,7 +123,36 @@ function convertAST2UmlClasses(node, relativePath, filesystem = false) {
|
|
|
123
123
|
imports.push(newImport);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
else if (childNode.type === 'FileLevelConstant') {
|
|
127
|
+
debug(`Adding file level constant ${childNode.name}`);
|
|
128
|
+
const [type, attributeType] = parseTypeName(childNode.typeName);
|
|
129
|
+
const umlClass = new umlClass_1.UmlClass({
|
|
130
|
+
name: childNode.name,
|
|
131
|
+
stereotype: umlClass_1.ClassStereotype.Constant,
|
|
132
|
+
absolutePath: filesystem
|
|
133
|
+
? path.resolve(relativePath) // resolve the absolute path
|
|
134
|
+
: relativePath,
|
|
135
|
+
relativePath,
|
|
136
|
+
attributes: [
|
|
137
|
+
{
|
|
138
|
+
name: childNode.name,
|
|
139
|
+
type,
|
|
140
|
+
attributeType,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
if (childNode?.initialValue?.type === 'NumberLiteral') {
|
|
145
|
+
umlClass.constants.push({
|
|
146
|
+
name: childNode.name,
|
|
147
|
+
value: parseInt(childNode.initialValue.number),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// TODO handle expressions. eg N_COINS * 2
|
|
151
|
+
umlClasses.push(umlClass);
|
|
152
|
+
}
|
|
153
|
+
else if (childNode.type !== 'PragmaDirective') {
|
|
154
|
+
debug(`node type "${childNode.type}" not parsed in ${relativePath}`);
|
|
155
|
+
}
|
|
127
156
|
});
|
|
128
157
|
}
|
|
129
158
|
else {
|
|
@@ -347,13 +376,22 @@ function addAssociations(nodes, umlClass) {
|
|
|
347
376
|
], umlClass);
|
|
348
377
|
// Array of user defined types
|
|
349
378
|
}
|
|
350
|
-
else if (node.typeName.type == 'ArrayTypeName'
|
|
351
|
-
node.typeName.baseTypeName.type ===
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
379
|
+
else if (node.typeName.type == 'ArrayTypeName') {
|
|
380
|
+
if (node.typeName.baseTypeName.type ===
|
|
381
|
+
'UserDefinedTypeName') {
|
|
382
|
+
const { umlClassName } = parseClassName(node.typeName.baseTypeName.namePath);
|
|
383
|
+
umlClass.addAssociation({
|
|
384
|
+
referenceType,
|
|
385
|
+
targetUmlClassName: umlClassName,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
else if (node.typeName.length?.type === 'Identifier') {
|
|
389
|
+
const { umlClassName } = parseClassName(node.typeName.length.name);
|
|
390
|
+
umlClass.addAssociation({
|
|
391
|
+
referenceType,
|
|
392
|
+
targetUmlClassName: umlClassName,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
357
395
|
}
|
|
358
396
|
break;
|
|
359
397
|
case 'UserDefinedTypeName':
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { UmlClass } from './umlClass';
|
|
2
2
|
export interface ClassOptions {
|
|
3
|
+
hideConstants?: boolean;
|
|
3
4
|
hideVariables?: boolean;
|
|
4
5
|
hideFunctions?: boolean;
|
|
6
|
+
hideModifiers?: boolean;
|
|
7
|
+
hideEvents?: boolean;
|
|
5
8
|
hideStructs?: boolean;
|
|
6
9
|
hideEnums?: boolean;
|
|
7
10
|
hideLibraries?: boolean;
|
|
@@ -14,7 +14,9 @@ const convertClass2Dot = (umlClass, options = {}) => {
|
|
|
14
14
|
umlClass.stereotype === umlClass_1.ClassStereotype.Abstract) ||
|
|
15
15
|
(options.hideStructs &&
|
|
16
16
|
umlClass.stereotype === umlClass_1.ClassStereotype.Struct) ||
|
|
17
|
-
(options.hideEnums && umlClass.stereotype === umlClass_1.ClassStereotype.Enum)
|
|
17
|
+
(options.hideEnums && umlClass.stereotype === umlClass_1.ClassStereotype.Enum) ||
|
|
18
|
+
(options.hideConstants &&
|
|
19
|
+
umlClass.stereotype === umlClass_1.ClassStereotype.Constant)) {
|
|
18
20
|
return '';
|
|
19
21
|
}
|
|
20
22
|
let dotString = `\n${umlClass.id} [label="{${dotClassTitle(umlClass, options)}`;
|
|
@@ -51,19 +53,23 @@ const dotClassTitle = (umlClass, options = {}) => {
|
|
|
51
53
|
case umlClass_1.ClassStereotype.Enum:
|
|
52
54
|
stereoName = 'Enum';
|
|
53
55
|
break;
|
|
56
|
+
case umlClass_1.ClassStereotype.Constant:
|
|
57
|
+
stereoName = 'Constant';
|
|
58
|
+
break;
|
|
54
59
|
default:
|
|
55
60
|
// Contract or undefined stereotype will just return the UmlClass name
|
|
56
61
|
return `${umlClass.name}${relativePath}`;
|
|
57
62
|
}
|
|
58
63
|
return `\\<\\<${stereoName}\\>\\>\\n${umlClass.name}${relativePath}`;
|
|
59
64
|
};
|
|
60
|
-
const dotAttributeVisibilities = (umlClass, options
|
|
65
|
+
const dotAttributeVisibilities = (umlClass, options) => {
|
|
61
66
|
if (umlClass.attributes.length === 0)
|
|
62
67
|
return '';
|
|
63
68
|
let dotString = '| ';
|
|
64
|
-
// if a struct or
|
|
69
|
+
// if a struct, enum or constant then no visibility group
|
|
65
70
|
if (umlClass.stereotype === umlClass_1.ClassStereotype.Struct ||
|
|
66
|
-
umlClass.stereotype === umlClass_1.ClassStereotype.Enum
|
|
71
|
+
umlClass.stereotype === umlClass_1.ClassStereotype.Enum ||
|
|
72
|
+
umlClass.stereotype === umlClass_1.ClassStereotype.Constant) {
|
|
67
73
|
return dotString + dotAttributes(umlClass.attributes, undefined, false);
|
|
68
74
|
}
|
|
69
75
|
// For each visibility group
|
|
@@ -109,7 +115,7 @@ const dotAttributes = (attributes, vizGroup, indent = true) => {
|
|
|
109
115
|
});
|
|
110
116
|
return dotString;
|
|
111
117
|
};
|
|
112
|
-
const dotOperatorVisibilities = (umlClass, options
|
|
118
|
+
const dotOperatorVisibilities = (umlClass, options) => {
|
|
113
119
|
if (umlClass.operators.length === 0)
|
|
114
120
|
return '';
|
|
115
121
|
let dotString = '| ';
|
|
@@ -140,11 +146,11 @@ const dotOperatorVisibilities = (umlClass, options = {}) => {
|
|
|
140
146
|
operators.push(operator);
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
|
-
dotString += dotOperators(umlClass, vizGroup, operators);
|
|
149
|
+
dotString += dotOperators(umlClass, vizGroup, operators, options);
|
|
144
150
|
}
|
|
145
151
|
return dotString;
|
|
146
152
|
};
|
|
147
|
-
const dotOperators = (umlClass, vizGroup, operators) => {
|
|
153
|
+
const dotOperators = (umlClass, vizGroup, operators, options) => {
|
|
148
154
|
// Skip if there are no operators
|
|
149
155
|
if (!operators || operators.length === 0) {
|
|
150
156
|
return '';
|
|
@@ -154,7 +160,12 @@ const dotOperators = (umlClass, vizGroup, operators) => {
|
|
|
154
160
|
const operatorsSortedByStereotype = operators.sort((a, b) => {
|
|
155
161
|
return b.stereotype - a.stereotype;
|
|
156
162
|
});
|
|
157
|
-
|
|
163
|
+
// Filter out any modifiers or events if options are flagged to hide them
|
|
164
|
+
let operatorsFiltered = operatorsSortedByStereotype.filter((o) => !((options.hideModifiers === true &&
|
|
165
|
+
o.stereotype === umlClass_1.OperatorStereotype.Modifier) ||
|
|
166
|
+
(options.hideEvents === true &&
|
|
167
|
+
o.stereotype === umlClass_1.OperatorStereotype.Event)));
|
|
168
|
+
for (const operator of operatorsFiltered) {
|
|
158
169
|
dotString += '\\ \\ \\ \\ ';
|
|
159
170
|
if (operator.stereotype > 0) {
|
|
160
171
|
dotString += dotOperatorStereotype(umlClass, operator.stereotype);
|
|
@@ -90,7 +90,7 @@ function addAssociationsToDot(umlClasses, classOptions = {}) {
|
|
|
90
90
|
exports.addAssociationsToDot = addAssociationsToDot;
|
|
91
91
|
function addAssociationToDot(sourceUmlClass, targetUmlClass, association, classOptions = {}) {
|
|
92
92
|
// do not include library or interface associations if hidden
|
|
93
|
-
// Or associations to Structs or
|
|
93
|
+
// Or associations to Structs, Enums or Constants if they are hidden
|
|
94
94
|
if ((classOptions.hideLibraries &&
|
|
95
95
|
(sourceUmlClass.stereotype === umlClass_1.ClassStereotype.Library ||
|
|
96
96
|
targetUmlClass.stereotype === umlClass_1.ClassStereotype.Library)) ||
|
|
@@ -103,7 +103,9 @@ function addAssociationToDot(sourceUmlClass, targetUmlClass, association, classO
|
|
|
103
103
|
(classOptions.hideStructs &&
|
|
104
104
|
targetUmlClass.stereotype === umlClass_1.ClassStereotype.Struct) ||
|
|
105
105
|
(classOptions.hideEnums &&
|
|
106
|
-
targetUmlClass.stereotype === umlClass_1.ClassStereotype.Enum)
|
|
106
|
+
targetUmlClass.stereotype === umlClass_1.ClassStereotype.Enum) ||
|
|
107
|
+
(classOptions.hideConstants &&
|
|
108
|
+
targetUmlClass.stereotype === umlClass_1.ClassStereotype.Constant)) {
|
|
107
109
|
return '';
|
|
108
110
|
}
|
|
109
111
|
let dotString = `\n${sourceUmlClass.id} -> ${targetUmlClass.id} [`;
|
|
@@ -29,8 +29,8 @@ const addStorageValues = async (url, contractAddress, storage, blockTag) => {
|
|
|
29
29
|
const valueVariables = storage.variables.filter((s) => !s.noValue);
|
|
30
30
|
const slots = valueVariables.map((s) => s.fromSlot);
|
|
31
31
|
const values = await (0, slotValues_1.getStorageValues)(url, contractAddress, slots, blockTag);
|
|
32
|
-
valueVariables.forEach((
|
|
33
|
-
|
|
32
|
+
valueVariables.forEach((valueVariable, i) => {
|
|
33
|
+
valueVariable.value = values[i];
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
36
|
exports.addStorageValues = addStorageValues;
|
|
@@ -49,7 +49,7 @@ const convertClasses2Storages = (contractName, umlClasses, contractFilename) =>
|
|
|
49
49
|
const contractFilenameError = contractFilename
|
|
50
50
|
? ` in filename "${contractFilename}"`
|
|
51
51
|
: '';
|
|
52
|
-
throw Error(`Failed to find contract with name "${contractName}"${contractFilenameError}
|
|
52
|
+
throw Error(`Failed to find contract with name "${contractName}"${contractFilenameError}.\nIs the \`-c --contract <name>\` option correct?`);
|
|
53
53
|
}
|
|
54
54
|
debug(`Found contract "${contractName}" in ${umlClass.absolutePath}`);
|
|
55
55
|
const storages = [];
|
|
@@ -177,25 +177,29 @@ const parseReferenceStorage = (attribute, umlClass, otherClasses, storages) => {
|
|
|
177
177
|
attributeType: baseAttributeType,
|
|
178
178
|
};
|
|
179
179
|
const { size: arrayItemSize } = (0, exports.calcStorageByteSize)(baseAttribute, umlClass, otherClasses);
|
|
180
|
-
const
|
|
180
|
+
const arraySlotSize = arrayItemSize > 16
|
|
181
|
+
? 32 * Math.ceil(arrayItemSize / 32)
|
|
182
|
+
: arrayItemSize;
|
|
183
|
+
const variables = [];
|
|
184
|
+
variables[0] = {
|
|
181
185
|
id: variableId++,
|
|
182
186
|
fromSlot: 0,
|
|
183
|
-
toSlot: Math.floor((
|
|
187
|
+
toSlot: Math.floor((arraySlotSize - 1) / 32),
|
|
184
188
|
byteSize: arrayItemSize,
|
|
185
189
|
byteOffset: 0,
|
|
186
190
|
type: baseType,
|
|
187
191
|
dynamic,
|
|
188
192
|
noValue: false,
|
|
189
193
|
};
|
|
190
|
-
const variables = [firstVariable];
|
|
191
194
|
if (arrayLength > 1) {
|
|
195
|
+
// For fixed length arrays. Dynamic arrays will have undefined arrayLength
|
|
192
196
|
for (let i = 1; i < arrayLength; i++) {
|
|
193
197
|
variables.push({
|
|
194
198
|
id: variableId++,
|
|
195
|
-
fromSlot: Math.floor((i *
|
|
196
|
-
toSlot: Math.floor(((i + 1) *
|
|
199
|
+
fromSlot: Math.floor((i * arraySlotSize) / 32),
|
|
200
|
+
toSlot: Math.floor(((i + 1) * arraySlotSize - 1) / 32),
|
|
197
201
|
byteSize: arrayItemSize,
|
|
198
|
-
byteOffset: (i *
|
|
202
|
+
byteOffset: (i * arraySlotSize) % 32,
|
|
199
203
|
type: baseType,
|
|
200
204
|
dynamic,
|
|
201
205
|
noValue: false,
|
|
@@ -205,7 +209,7 @@ const parseReferenceStorage = (attribute, umlClass, otherClasses, storages) => {
|
|
|
205
209
|
// recursively add storage
|
|
206
210
|
if (baseAttributeType !== umlClass_1.AttributeType.Elementary) {
|
|
207
211
|
const referenceStorage = (0, exports.parseReferenceStorage)(baseAttribute, umlClass, otherClasses, storages);
|
|
208
|
-
|
|
212
|
+
variables[0].referenceStorageId = referenceStorage?.id;
|
|
209
213
|
}
|
|
210
214
|
const newStorage = {
|
|
211
215
|
id: storageId++,
|
package/lib/parserFiles.js
CHANGED
|
@@ -48,7 +48,12 @@ function getSolidityFilesFromFolderOrFile(folderOrFilePath, ignoreFilesOrFolders
|
|
|
48
48
|
preserveSymlinks: true,
|
|
49
49
|
})
|
|
50
50
|
.on('data', (file) => {
|
|
51
|
-
if (
|
|
51
|
+
if (
|
|
52
|
+
// If file has sol extension
|
|
53
|
+
(0, path_1.extname)(file.path) === '.sol' &&
|
|
54
|
+
// and file and not a folder
|
|
55
|
+
// Note Foundry's forge outputs folders with the same name as the source file
|
|
56
|
+
file.stats.isFile())
|
|
52
57
|
files.push(file.path);
|
|
53
58
|
})
|
|
54
59
|
.on('end', () => {
|
package/lib/sol2uml.js
CHANGED
|
@@ -60,6 +60,9 @@ If an Ethereum address with a 0x prefix is passed, the verified source code from
|
|
|
60
60
|
.option('-hv, --hideVariables', 'hide variables from contracts, interfaces, structs and enums', false)
|
|
61
61
|
.option('-hf, --hideFunctions', 'hide functions from contracts, interfaces and libraries', false)
|
|
62
62
|
.option('-hp, --hidePrivates', 'hide private and internal attributes and operators', false)
|
|
63
|
+
.option('-hm, --hideModifiers', 'hide modifier functions from contracts', false)
|
|
64
|
+
.option('-ht, --hideEvents', 'hide events from contracts, interfaces and libraries', false)
|
|
65
|
+
.option('-hc, --hideConstants', 'hide file level constants', false)
|
|
63
66
|
.option('-he, --hideEnums', 'hide enum types', false)
|
|
64
67
|
.option('-hs, --hideStructs', 'hide data structures', false)
|
|
65
68
|
.option('-hl, --hideLibraries', 'hide libraries', false)
|
|
@@ -109,6 +112,10 @@ WARNING: sol2uml does not use the Solidity compiler so may differ with solc. A k
|
|
|
109
112
|
...command.parent._optionValues,
|
|
110
113
|
...options,
|
|
111
114
|
};
|
|
115
|
+
// If not an address and the contractName option has not been specified
|
|
116
|
+
if (!(0, regEx_1.isAddress)(fileFolderAddress) && !combinedOptions.contract) {
|
|
117
|
+
throw Error(`Must use the \`-c, --contract <name>\` option to specify the contract to draw the storage diagram for when sourcing from local files.\nThis option is not needed when sourcing from a blockchain explorer with a contract address.`);
|
|
118
|
+
}
|
|
112
119
|
let { umlClasses, contractName } = await (0, parserGeneral_1.parserUmlClasses)(fileFolderAddress, combinedOptions);
|
|
113
120
|
contractName = combinedOptions.contract || contractName;
|
|
114
121
|
const storages = (0, converterClasses2Storage_1.convertClasses2Storages)(contractName, umlClasses, combinedOptions.contractFile);
|
package/lib/umlClass.d.ts
CHANGED
package/lib/umlClass.js
CHANGED
|
@@ -18,6 +18,7 @@ var ClassStereotype;
|
|
|
18
18
|
ClassStereotype[ClassStereotype["Contract"] = 4] = "Contract";
|
|
19
19
|
ClassStereotype[ClassStereotype["Struct"] = 5] = "Struct";
|
|
20
20
|
ClassStereotype[ClassStereotype["Enum"] = 6] = "Enum";
|
|
21
|
+
ClassStereotype[ClassStereotype["Constant"] = 7] = "Constant";
|
|
21
22
|
})(ClassStereotype = exports.ClassStereotype || (exports.ClassStereotype = {}));
|
|
22
23
|
var OperatorStereotype;
|
|
23
24
|
(function (OperatorStereotype) {
|