Skip to content

Commit

Permalink
fix: storage diagrams that have chained imports
Browse files Browse the repository at this point in the history
  • Loading branch information
naddison36 committed Nov 15, 2023
1 parent bf9ce4e commit b75d0c2
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 24 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,5 @@ sol2uml uses [@solidity-parser/parser](https://github.com/solidity-parser/parser
The [Solidity language grammar](https://solidity.readthedocs.io/en/develop/miscellaneous.html#language-grammar) is published with each major release.

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.

The `diff` command use's Google's [Diff Match and Patch library](https://github.com/google/diff-match-patch).
32 changes: 22 additions & 10 deletions lib/associations.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/contracts/chainedImports/Base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ pragma solidity ^0.8.17;
contract Base {
uint256 public baseNum;
}

contract BaseAliased {
address public baseAddress;
bool isAlias;
}
2 changes: 1 addition & 1 deletion src/contracts/chainedImports/BaseImport.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import { Base } from "./Base.sol";
import { Base, BaseAliased } from "./Base.sol";

contract Transient {
uint256 public transNum;
Expand Down
4 changes: 2 additions & 2 deletions src/contracts/chainedImports/Concrete.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import { Base } from "./BaseImport.sol";
import {Base, BaseAliased as Base2} from './BaseImport.sol';

contract Concrete is Base {
contract Concrete is Base, Base2 {
uint256 public concreteNum;
}
44 changes: 33 additions & 11 deletions src/ts/associations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const findAssociatedClass = (
// Could not find a link so now need to recursively look at imports of imports
// add to already recursively processed files to avoid getting stuck in circular imports
searchedAbsolutePaths.push(sourceUmlClass.absolutePath)
return findImplicitImport(
return findChainedImport(
association,
sourceUmlClass,
umlClasses,
Expand All @@ -40,17 +40,17 @@ const isAssociated = (
association: Association,
sourceUmlClass: UmlClass,
targetUmlClass: UmlClass,
targetParentmlClass: UmlClass,
targetParentUmlClass: UmlClass,
): boolean => {
if (association.parentUmlClassName) {
return (
// class is in the same source file
(association.targetUmlClassName === targetUmlClass.name &&
association.parentUmlClassName === targetParentmlClass?.name &&
association.parentUmlClassName === targetParentUmlClass?.name &&
sourceUmlClass.absolutePath === targetUmlClass.absolutePath) ||
// imported classes with no explicit import names
(association.targetUmlClassName === targetUmlClass.name &&
association.parentUmlClassName === targetParentmlClass?.name &&
association.parentUmlClassName === targetParentUmlClass?.name &&
sourceUmlClass.imports.some(
(i) =>
i.absolutePath === targetUmlClass.absolutePath &&
Expand Down Expand Up @@ -110,18 +110,26 @@ const isAssociated = (
)
}

const findImplicitImport = (
const findChainedImport = (
association: Association,
sourceUmlClass: UmlClass,
umlClasses: readonly UmlClass[],
searchedRelativePaths: string[],
): UmlClass | undefined => {
// Get all implicit imports. That is, imports that do not explicitly import contracts or interfaces.
const implicitImports = sourceUmlClass.imports.filter(
(i) => i.classNames.length === 0,
// Get all valid imports. That is, imports that do not explicitly import contracts or interfaces
// or explicitly import the source class
const imports = sourceUmlClass.imports.filter(
(i) =>
i.classNames.length === 0 ||
i.classNames.some(
(cn) =>
(association.targetUmlClassName === cn.className &&
!cn.alias) ||
association.targetUmlClassName === cn.alias,
),
)
// For each implicit import
for (const importDetail of implicitImports) {
// For each import
for (const importDetail of imports) {
// Find a class with the same absolute path as the import so we can get the new imports
const newSourceUmlClass = umlClasses.find(
(c) => c.absolutePath === importDetail.absolutePath,
Expand All @@ -135,14 +143,28 @@ const findImplicitImport = (
// Have already recursively looked for imports of imports in this file
continue
}
// TODO need to handle imports that use aliases as the association will not be found

// find class linked to the association without aliased imports
const umlClass = findAssociatedClass(
association,
newSourceUmlClass,
umlClasses,
searchedRelativePaths,
)
if (umlClass) return umlClass

// find all aliased imports
const aliasedImports = importDetail.classNames.filter((cn) => cn.alias)
// For each aliased import
for (const aliasedImport of aliasedImports) {
const umlClass = findAssociatedClass(
{ ...association, targetUmlClassName: aliasedImport.className },
newSourceUmlClass,
umlClasses,
searchedRelativePaths,
)
if (umlClass) return umlClass
}
}
return undefined
}
11 changes: 11 additions & 0 deletions tests/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ sol2uml storage 0x2fdfbb2b905484f1445e23a97c97f65fe0e43dec -d -s 0xc0f42f73b8f01
sol2uml storage 0x2fdfbb2b905484f1445e23a97c97f65fe0e43dec -d -s 0xc0f42f73b8f01849a2dd99753524d4ba14317eb3 \
--slotNames OUSD.governor,OUSD.pending.governor,OUSD.reentry.status,0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc

## From issue https://github.com/naddison36/sol2uml/issues/175
sol2uml storage 0x8115366Ca7Cf280a760f0bC0F6Db3026e2437115 -v --data --storage 0xC13e21B648A5Ee794902342038FF3aDAB66BE987
sol2uml storage 0x8115366Ca7Cf280a760f0bC0F6Db3026e2437115 -v --data --storage 0xC13e21B648A5Ee794902342038FF3aDAB66BE987 --hideExpand ______gap --hideValues

# Test import of imports including aliased imports
sol2uml storage -v -c Concrete ../src/contracts/chainedImports

# Class

## Maker DSR Strategy Implementation
Expand All @@ -190,3 +197,7 @@ sol2uml ../src/contracts -b TestStorage -v
sol2uml 0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4 -v --network base
## USDC on Base
sol2uml 0x1833C6171E0A3389B156eAedB301CFfbf328B463 -v --network base

# All OpenZeppelin contracts
sol2uml ../node_modules/@openzeppelin/contracts

0 comments on commit b75d0c2

Please sign in to comment.