sol2uml 2.5.18 → 2.5.20

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 CHANGED
@@ -373,3 +373,5 @@ sol2uml uses [@solidity-parser/parser](https://github.com/solidity-parser/parser
373
373
  The [Solidity language grammar](https://solidity.readthedocs.io/en/develop/miscellaneous.html#language-grammar) is published with each major release.
374
374
 
375
375
  The diagrams are generated using [viz.js](https://github.com/mdaines/viz.js/) which uses [Graphviz](http://www.graphviz.org/) to render a [Scalable Vector Graphics (SVG)](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) file. [Graphviz Online](https://dreampuf.github.io/GraphvizOnline/) allows dot files to be edited and rendered into a SVG dynamically.
376
+
377
+ The `diff` command use's Google's [Diff Match and Patch library](https://github.com/google/diff-match-patch).
@@ -13,42 +13,48 @@ const findAssociatedClass = (association, sourceUmlClass, umlClasses, searchedAb
13
13
  // If a link was found
14
14
  if (umlClass)
15
15
  return umlClass;
16
- // Could not find a link so now need to recursively look at imports of imports
16
+ // Could not find association so now need to recursively look at imports of imports
17
17
  // add to already recursively processed files to avoid getting stuck in circular imports
18
18
  searchedAbsolutePaths.push(sourceUmlClass.absolutePath);
19
- return findImplicitImport(association, sourceUmlClass, umlClasses, searchedAbsolutePaths);
19
+ const importedType = findChainedImport(association, sourceUmlClass, umlClasses, searchedAbsolutePaths);
20
+ if (importedType)
21
+ return importedType;
22
+ // Still could not find association so now need to recursively look for inherited types
23
+ const inheritedType = findInheritedType(association, sourceUmlClass, umlClasses);
24
+ if (inheritedType)
25
+ return inheritedType;
26
+ return undefined;
20
27
  };
21
28
  exports.findAssociatedClass = findAssociatedClass;
22
29
  // Tests if source class can be linked to the target class via an association
23
- const isAssociated = (association, sourceUmlClass, targetUmlClass, targetParentmlClass) => {
30
+ const isAssociated = (association, sourceUmlClass, targetUmlClass, targetParentUmlClass) => {
24
31
  if (association.parentUmlClassName) {
25
32
  return (
26
33
  // class is in the same source file
27
34
  (association.targetUmlClassName === targetUmlClass.name &&
28
- association.parentUmlClassName === targetParentmlClass?.name &&
35
+ association.parentUmlClassName === targetParentUmlClass?.name &&
29
36
  sourceUmlClass.absolutePath === targetUmlClass.absolutePath) ||
30
37
  // imported classes with no explicit import names
31
38
  (association.targetUmlClassName === targetUmlClass.name &&
32
- association.parentUmlClassName === targetParentmlClass?.name &&
39
+ association.parentUmlClassName === targetParentUmlClass?.name &&
33
40
  sourceUmlClass.imports.some((i) => i.absolutePath === targetUmlClass.absolutePath &&
34
41
  i.classNames.length === 0)) ||
35
42
  // imported classes with explicit import names or import aliases
36
43
  sourceUmlClass.imports.some((importLink) => importLink.absolutePath === targetUmlClass.absolutePath &&
37
44
  importLink.classNames.some((importedClass) =>
38
45
  // If a parent contract with no import alias
39
- (association.parentUmlClassName !== undefined &&
46
+ (association.targetUmlClassName ===
47
+ targetUmlClass.name &&
40
48
  association.parentUmlClassName ===
41
49
  importedClass.className &&
42
- importedClass.className ===
43
- targetUmlClass.name &&
44
50
  importedClass.alias == undefined) ||
45
51
  // If a parent contract with import alias
46
- (association.parentUmlClassName !== undefined &&
52
+ (association.targetUmlClassName ===
53
+ targetUmlClass.name &&
47
54
  association.parentUmlClassName ===
48
- importedClass.alias &&
49
- importedClass.className ===
50
- targetUmlClass.name))));
55
+ importedClass.alias))));
51
56
  }
57
+ // No parent class in the association
52
58
  return (
53
59
  // class is in the same source file
54
60
  (association.targetUmlClassName === targetUmlClass.name &&
@@ -70,11 +76,48 @@ const isAssociated = (association, sourceUmlClass, targetUmlClass, targetParentm
70
76
  importedClass.alias &&
71
77
  importedClass.className === targetUmlClass.name))));
72
78
  };
73
- const findImplicitImport = (association, sourceUmlClass, umlClasses, searchedRelativePaths) => {
74
- // Get all implicit imports. That is, imports that do not explicitly import contracts or interfaces.
75
- const implicitImports = sourceUmlClass.imports.filter((i) => i.classNames.length === 0);
76
- // For each implicit import
77
- for (const importDetail of implicitImports) {
79
+ const findInheritedType = (association, sourceUmlClass, umlClasses) => {
80
+ // Get all realized associations.
81
+ const parentAssociations = sourceUmlClass.getParentContracts();
82
+ // For each parent association
83
+ for (const parentAssociation of parentAssociations) {
84
+ const parent = (0, exports.findAssociatedClass)(parentAssociation, sourceUmlClass, umlClasses);
85
+ if (!parent)
86
+ continue;
87
+ // For each struct on the parent
88
+ for (const structId of parent.structs) {
89
+ const structUmlClass = umlClasses.find((c) => c.id === structId);
90
+ if (!structUmlClass)
91
+ continue;
92
+ if (structUmlClass.name === association.targetUmlClassName) {
93
+ return structUmlClass;
94
+ }
95
+ }
96
+ // For each enum on the parent
97
+ for (const enumId of parent.enums) {
98
+ const enumUmlClass = umlClasses.find((c) => c.id === enumId);
99
+ if (!enumUmlClass)
100
+ continue;
101
+ if (enumUmlClass.name === association.targetUmlClassName) {
102
+ return enumUmlClass;
103
+ }
104
+ }
105
+ // Recursively look for inherited types
106
+ const targetClass = findInheritedType(association, parent, umlClasses);
107
+ if (targetClass)
108
+ return targetClass;
109
+ }
110
+ return undefined;
111
+ };
112
+ const findChainedImport = (association, sourceUmlClass, umlClasses, searchedRelativePaths) => {
113
+ // Get all valid imports. That is, imports that do not explicitly import contracts or interfaces
114
+ // or explicitly import the source class
115
+ const imports = sourceUmlClass.imports.filter((i) => i.classNames.length === 0 ||
116
+ i.classNames.some((cn) => (association.targetUmlClassName === cn.className &&
117
+ !cn.alias) ||
118
+ association.targetUmlClassName === cn.alias));
119
+ // For each import
120
+ for (const importDetail of imports) {
78
121
  // Find a class with the same absolute path as the import so we can get the new imports
79
122
  const newSourceUmlClass = umlClasses.find((c) => c.absolutePath === importDetail.absolutePath);
80
123
  if (!newSourceUmlClass) {
@@ -86,10 +129,18 @@ const findImplicitImport = (association, sourceUmlClass, umlClasses, searchedRel
86
129
  // Have already recursively looked for imports of imports in this file
87
130
  continue;
88
131
  }
89
- // TODO need to handle imports that use aliases as the association will not be found
132
+ // find class linked to the association without aliased imports
90
133
  const umlClass = (0, exports.findAssociatedClass)(association, newSourceUmlClass, umlClasses, searchedRelativePaths);
91
134
  if (umlClass)
92
135
  return umlClass;
136
+ // find all aliased imports
137
+ const aliasedImports = importDetail.classNames.filter((cn) => cn.alias);
138
+ // For each aliased import
139
+ for (const aliasedImport of aliasedImports) {
140
+ const umlClass = (0, exports.findAssociatedClass)({ ...association, targetUmlClassName: aliasedImport.className }, newSourceUmlClass, umlClasses, searchedRelativePaths);
141
+ if (umlClass)
142
+ return umlClass;
143
+ }
93
144
  }
94
145
  return undefined;
95
146
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sol2uml",
3
- "version": "2.5.18",
3
+ "version": "2.5.20",
4
4
  "description": "Solidity contract visualisation tool.",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",