sol2uml 2.1.6 → 2.1.7
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 +1 -0
- package/lib/converterAST2Classes.js +48 -10
- package/lib/converterClass2Dot.d.ts +1 -0
- package/lib/converterClass2Dot.js +9 -3
- package/lib/converterClasses2Dot.js +4 -2
- package/lib/converterClasses2Storage.js +11 -7
- package/lib/sol2uml.js +1 -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,7 @@ 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
|
+
-hc, --hideConstants hide file level constants (default: false)
|
|
100
101
|
-he, --hideEnums hide enum types (default: false)
|
|
101
102
|
-hs, --hideStructs hide data structures (default: false)
|
|
102
103
|
-hl, --hideLibraries hide libraries (default: false)
|
|
@@ -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':
|
|
@@ -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,6 +53,9 @@ 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}`;
|
|
@@ -61,9 +66,10 @@ 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
|
|
@@ -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} [`;
|
|
@@ -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/sol2uml.js
CHANGED
|
@@ -60,6 +60,7 @@ 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('-hc, --hideConstants', 'hide file level constants', false)
|
|
63
64
|
.option('-he, --hideEnums', 'hide enum types', false)
|
|
64
65
|
.option('-hs, --hideStructs', 'hide data structures', false)
|
|
65
66
|
.option('-hl, --hideLibraries', 'hide libraries', false)
|
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) {
|