sol2uml 2.4.2 → 2.5.0
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/LICENSE +1 -1
- package/README.md +24 -4
- package/lib/SlotValueCache.d.ts +31 -0
- package/lib/SlotValueCache.js +65 -0
- package/lib/associations.d.ts +1 -1
- package/lib/associations.js +1 -21
- package/lib/converterAST2Classes.d.ts +12 -1
- package/lib/converterAST2Classes.js +33 -7
- package/lib/converterClass2Dot.d.ts +4 -0
- package/lib/converterClasses2Dot.js +3 -2
- package/lib/converterClasses2Storage.d.ts +53 -21
- package/lib/converterClasses2Storage.js +451 -180
- package/lib/converterStorage2Dot.d.ts +7 -3
- package/lib/converterStorage2Dot.js +53 -28
- package/lib/filterClasses.d.ts +4 -4
- package/lib/filterClasses.js +2 -1
- package/lib/parserEtherscan.d.ts +20 -2
- package/lib/parserEtherscan.js +38 -5
- package/lib/parserFiles.d.ts +3 -3
- package/lib/parserFiles.js +2 -2
- package/lib/slotValues.d.ts +48 -2
- package/lib/slotValues.js +260 -23
- package/lib/sol2uml.js +30 -15
- package/lib/squashClasses.d.ts +3 -3
- package/lib/squashClasses.js +2 -2
- package/lib/writerFiles.d.ts +21 -1
- package/lib/writerFiles.js +21 -2
- package/package.json +5 -5
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const convertStorages2Dot: (
|
|
1
|
+
import { StorageSection } from './converterClasses2Storage';
|
|
2
|
+
export declare const convertStorages2Dot: (storageSections: readonly StorageSection[], options: {
|
|
3
3
|
data: boolean;
|
|
4
|
+
backColor: string;
|
|
5
|
+
shapeColor: string;
|
|
6
|
+
fillColor: string;
|
|
7
|
+
textColor: string;
|
|
4
8
|
}) => string;
|
|
5
|
-
export declare function convertStorage2Dot(
|
|
9
|
+
export declare function convertStorage2Dot(storageSection: StorageSection, dotString: string, options: {
|
|
6
10
|
data: boolean;
|
|
7
11
|
}): string;
|
|
@@ -2,23 +2,25 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertStorage2Dot = exports.convertStorages2Dot = void 0;
|
|
4
4
|
const converterClasses2Storage_1 = require("./converterClasses2Storage");
|
|
5
|
+
const umlClass_1 = require("./umlClass");
|
|
5
6
|
const debug = require('debug')('sol2uml');
|
|
6
|
-
const convertStorages2Dot = (
|
|
7
|
+
const convertStorages2Dot = (storageSections, options) => {
|
|
7
8
|
let dotString = `
|
|
8
9
|
digraph StorageDiagram {
|
|
9
10
|
rankdir=LR
|
|
10
|
-
color=black
|
|
11
11
|
arrowhead=open
|
|
12
|
-
|
|
12
|
+
bgcolor="${options.backColor}"
|
|
13
|
+
edge [color="${options.shapeColor}"]
|
|
14
|
+
node [shape=record, style=filled, color="${options.shapeColor}", fillcolor="${options.fillColor}", fontcolor="${options.textColor}", fontname="Courier New"]`;
|
|
13
15
|
// process contract and the struct storages
|
|
14
|
-
|
|
16
|
+
storageSections.forEach((storage) => {
|
|
15
17
|
dotString = convertStorage2Dot(storage, dotString, options);
|
|
16
18
|
});
|
|
17
19
|
// link contract and structs to structs
|
|
18
|
-
|
|
20
|
+
storageSections.forEach((slot) => {
|
|
19
21
|
slot.variables.forEach((storage) => {
|
|
20
|
-
if (storage.
|
|
21
|
-
dotString += `\n ${slot.id}:${storage.id} -> ${storage.
|
|
22
|
+
if (storage.referenceSectionId) {
|
|
23
|
+
dotString += `\n ${slot.id}:${storage.id} -> ${storage.referenceSectionId}`;
|
|
22
24
|
}
|
|
23
25
|
});
|
|
24
26
|
});
|
|
@@ -28,34 +30,50 @@ node [shape=record, style=filled, fillcolor=gray95 fontname="Courier New"]`;
|
|
|
28
30
|
return dotString;
|
|
29
31
|
};
|
|
30
32
|
exports.convertStorages2Dot = convertStorages2Dot;
|
|
31
|
-
function convertStorage2Dot(
|
|
33
|
+
function convertStorage2Dot(storageSection, dotString, options) {
|
|
32
34
|
// write storage header with name and optional address
|
|
33
|
-
dotString += `\n${
|
|
35
|
+
dotString += `\n${storageSection.id} [label="${storageSection.name} \\<\\<${storageSection.type}\\>\\>\\n${storageSection.address || storageSection.offset || ''}`;
|
|
34
36
|
dotString += ' | {';
|
|
35
|
-
const startingVariables =
|
|
37
|
+
const startingVariables = storageSection.variables.filter((s) => s.byteOffset === 0);
|
|
38
|
+
// for each slot displayed, does is have any variables with parsed data?
|
|
39
|
+
const displayData = startingVariables.map((startVar) => storageSection.variables.some((variable) => variable.fromSlot === startVar.fromSlot && variable.parsedValue));
|
|
40
|
+
const linePad = '\\n\\ ';
|
|
36
41
|
// write slot numbers
|
|
37
|
-
|
|
42
|
+
const dataLine = options.data ? linePad : '';
|
|
43
|
+
dotString +=
|
|
44
|
+
storageSection.offset || storageSection.mapping
|
|
45
|
+
? `{ offset${dataLine}`
|
|
46
|
+
: `{ slot${dataLine}`;
|
|
38
47
|
startingVariables.forEach((variable, i) => {
|
|
48
|
+
const dataLine = options.data && displayData[i] ? linePad : '';
|
|
39
49
|
if (variable.fromSlot === variable.toSlot) {
|
|
40
|
-
dotString +=
|
|
50
|
+
dotString += ` | ${variable.fromSlot}${dataLine}`;
|
|
41
51
|
}
|
|
42
52
|
else {
|
|
43
|
-
dotString +=
|
|
53
|
+
dotString += ` | ${variable.fromSlot}-${variable.toSlot}${dataLine}`;
|
|
44
54
|
}
|
|
45
55
|
});
|
|
46
56
|
// write slot values if available
|
|
47
57
|
if (options.data) {
|
|
48
|
-
dotString +=
|
|
58
|
+
dotString += `} | {value${dataLine}`;
|
|
49
59
|
startingVariables.forEach((variable, i) => {
|
|
50
|
-
|
|
60
|
+
if (displayData[i]) {
|
|
61
|
+
dotString += ` | ${variable.slotValue || ''}${linePad}`;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
dotString += ` | `;
|
|
65
|
+
}
|
|
51
66
|
});
|
|
52
67
|
}
|
|
53
|
-
const contractVariablePrefix =
|
|
54
|
-
|
|
68
|
+
const contractVariablePrefix = storageSection.type === converterClasses2Storage_1.StorageSectionType.Contract
|
|
69
|
+
? '\\<inherited contract\\>.'
|
|
70
|
+
: '';
|
|
71
|
+
const dataLine2 = options.data ? `\\ndecoded data` : '';
|
|
72
|
+
dotString += `} | { type: ${contractVariablePrefix}variable (bytes)${dataLine2}`;
|
|
55
73
|
// For each slot
|
|
56
74
|
startingVariables.forEach((variable) => {
|
|
57
75
|
// Get all the storage variables in this slot
|
|
58
|
-
const slotVariables =
|
|
76
|
+
const slotVariables = storageSection.variables.filter((s) => s.fromSlot === variable.fromSlot);
|
|
59
77
|
const usedBytes = slotVariables.reduce((acc, s) => acc + s.byteSize, 0);
|
|
60
78
|
if (usedBytes < 32) {
|
|
61
79
|
// Create an unallocated variable for display purposes
|
|
@@ -66,20 +84,22 @@ function convertStorage2Dot(storage, dotString, options) {
|
|
|
66
84
|
byteSize: 32 - usedBytes,
|
|
67
85
|
byteOffset: usedBytes,
|
|
68
86
|
type: 'unallocated',
|
|
87
|
+
attributeType: umlClass_1.AttributeType.UserDefined,
|
|
69
88
|
dynamic: false,
|
|
70
|
-
|
|
89
|
+
displayValue: false,
|
|
90
|
+
getValue: false,
|
|
71
91
|
contractName: variable.contractName,
|
|
72
|
-
|
|
92
|
+
name: '',
|
|
73
93
|
});
|
|
74
94
|
}
|
|
75
95
|
const slotVariablesReversed = slotVariables.reverse();
|
|
76
96
|
// For each variable in the slot
|
|
77
97
|
slotVariablesReversed.forEach((variable, i) => {
|
|
78
98
|
if (i === 0) {
|
|
79
|
-
dotString += ` | { ${dotVariable(variable,
|
|
99
|
+
dotString += ` | { ${dotVariable(variable, storageSection.name)} `;
|
|
80
100
|
}
|
|
81
101
|
else {
|
|
82
|
-
dotString += ` | ${dotVariable(variable,
|
|
102
|
+
dotString += ` | ${dotVariable(variable, storageSection.name)} `;
|
|
83
103
|
}
|
|
84
104
|
});
|
|
85
105
|
dotString += '}';
|
|
@@ -89,12 +109,17 @@ function convertStorage2Dot(storage, dotString, options) {
|
|
|
89
109
|
return dotString;
|
|
90
110
|
}
|
|
91
111
|
exports.convertStorage2Dot = convertStorage2Dot;
|
|
92
|
-
const dotVariable = (
|
|
93
|
-
const port =
|
|
94
|
-
const contractNamePrefix =
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
const dotVariable = (variable, contractName) => {
|
|
113
|
+
const port = variable.referenceSectionId !== undefined ? `<${variable.id}>` : '';
|
|
114
|
+
const contractNamePrefix = variable.contractName !== contractName
|
|
115
|
+
? `${variable.contractName}.`
|
|
116
|
+
: '';
|
|
117
|
+
const variableValue = variable.parsedValue
|
|
118
|
+
? `\\n\\ ${variable.parsedValue}`
|
|
119
|
+
: '';
|
|
120
|
+
const variableName = variable.name
|
|
121
|
+
? `: ${contractNamePrefix}${variable.name}`
|
|
97
122
|
: '';
|
|
98
|
-
return `${port} ${
|
|
123
|
+
return `${port} ${variable.type}${variableName} (${variable.byteSize})${variableValue}`;
|
|
99
124
|
};
|
|
100
125
|
//# sourceMappingURL=converterStorage2Dot.js.map
|
package/lib/filterClasses.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { ClassOptions } from './converterClass2Dot';
|
|
|
7
7
|
* @param options sol2uml class options
|
|
8
8
|
* @return umlClasses filtered list of UML classes of type `UMLClass`
|
|
9
9
|
*/
|
|
10
|
-
export declare const filterHiddenClasses: (umlClasses: UmlClass[], options: ClassOptions) => UmlClass[];
|
|
10
|
+
export declare const filterHiddenClasses: (umlClasses: readonly UmlClass[], options: ClassOptions) => UmlClass[];
|
|
11
11
|
/**
|
|
12
12
|
* Finds all the UML classes that have an association with a list of base contract names.
|
|
13
13
|
* The associated classes can be contracts, abstract contracts, interfaces, libraries, enums, structs or constants.
|
|
@@ -16,7 +16,7 @@ export declare const filterHiddenClasses: (umlClasses: UmlClass[], options: Clas
|
|
|
16
16
|
* @param depth limit the number of associations from the base contract.
|
|
17
17
|
* @return filteredUmlClasses list of UML classes of type `UMLClass`
|
|
18
18
|
*/
|
|
19
|
-
export declare const classesConnectedToBaseContracts: (umlClasses: UmlClass[], baseContractNames: string[], depth?: number) => UmlClass[];
|
|
19
|
+
export declare const classesConnectedToBaseContracts: (umlClasses: readonly UmlClass[], baseContractNames: readonly string[], depth?: number) => UmlClass[];
|
|
20
20
|
/**
|
|
21
21
|
* Finds all the UML classes that have an association with a base contract name.
|
|
22
22
|
* The associated classes can be contracts, abstract contracts, interfaces, libraries, enums, structs or constants.
|
|
@@ -26,7 +26,7 @@ export declare const classesConnectedToBaseContracts: (umlClasses: UmlClass[], b
|
|
|
26
26
|
* @param depth limit the number of associations from the base contract.
|
|
27
27
|
* @return filteredUmlClasses list of UML classes of type `UMLClass`
|
|
28
28
|
*/
|
|
29
|
-
export declare const classesConnectedToBaseContract: (umlClasses: UmlClass[], baseContractName: string, weightedDirectedGraph: WeightedDiGraph, depth?: number) => {
|
|
29
|
+
export declare const classesConnectedToBaseContract: (umlClasses: readonly UmlClass[], baseContractName: string, weightedDirectedGraph: WeightedDiGraph, depth?: number) => {
|
|
30
30
|
[contractName: string]: UmlClass;
|
|
31
31
|
};
|
|
32
|
-
export declare const topologicalSortClasses: (umlClasses: UmlClass[]) => UmlClass[];
|
|
32
|
+
export declare const topologicalSortClasses: (umlClasses: readonly UmlClass[]) => UmlClass[];
|
package/lib/filterClasses.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.topologicalSortClasses = exports.classesConnectedToBaseContract = export
|
|
|
4
4
|
const js_graph_algorithms_1 = require("js-graph-algorithms");
|
|
5
5
|
const umlClass_1 = require("./umlClass");
|
|
6
6
|
const associations_1 = require("./associations");
|
|
7
|
+
const debug = require('debug')('sol2uml');
|
|
7
8
|
/**
|
|
8
9
|
* Filter out any UML Class types that are to be hidden.
|
|
9
10
|
* @param umlClasses array of UML classes of type `UMLClass`
|
|
@@ -85,7 +86,7 @@ function loadWeightedDirectedGraph(umlClasses) {
|
|
|
85
86
|
continue;
|
|
86
87
|
}
|
|
87
88
|
const isTarget = umlClasses.find((u) => u.id === targetUmlClass.id);
|
|
88
|
-
|
|
89
|
+
debug(`isTarget ${isTarget} Adding edge from ${sourceUmlClass.name} with id ${sourceUmlClass.id} to ${targetUmlClass.name} with id ${targetUmlClass.id} and type ${targetUmlClass.stereotype}`);
|
|
89
90
|
weightedDirectedGraph.addEdge(new js_graph_algorithms_1.Edge(sourceUmlClass.id, targetUmlClass.id, 1));
|
|
90
91
|
}
|
|
91
92
|
}
|
package/lib/parserEtherscan.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ASTNode } from '@solidity-parser/parser/dist/src/ast-types';
|
|
2
2
|
import { UmlClass } from './umlClass';
|
|
3
|
+
export interface Remapping {
|
|
4
|
+
from: RegExp;
|
|
5
|
+
to: string;
|
|
6
|
+
}
|
|
3
7
|
export declare const networks: readonly ["mainnet", "ropsten", "kovan", "rinkeby", "goerli", "sepolia", "polygon", "testnet.polygon", "arbitrum", "testnet.arbitrum", "avalanche", "testnet.avalanche", "bsc", "testnet.bsc", "crono", "fantom", "testnet.fantom", "moonbeam", "optimistic", "kovan-optimistic", "gnosisscan"];
|
|
4
|
-
export type Network = typeof networks[number];
|
|
8
|
+
export type Network = (typeof networks)[number];
|
|
5
9
|
export declare class EtherscanParser {
|
|
6
10
|
protected apikey: string;
|
|
7
11
|
network: Network;
|
|
@@ -37,11 +41,25 @@ export declare class EtherscanParser {
|
|
|
37
41
|
* @param contractAddress Ethereum contract address with a 0x prefix
|
|
38
42
|
*/
|
|
39
43
|
getSourceCode(contractAddress: string): Promise<{
|
|
40
|
-
files: {
|
|
44
|
+
files: readonly {
|
|
41
45
|
code: string;
|
|
42
46
|
filename: string;
|
|
43
47
|
}[];
|
|
44
48
|
contractName: string;
|
|
45
49
|
compilerVersion: string;
|
|
50
|
+
remappings: Remapping[];
|
|
46
51
|
}>;
|
|
47
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* Parses Ethersan's remappings config in its API response
|
|
55
|
+
* @param rawMappings
|
|
56
|
+
*/
|
|
57
|
+
export declare const parseRemappings: (rawMappings: string[]) => Remapping[];
|
|
58
|
+
/**
|
|
59
|
+
* Parses a single mapping. For example
|
|
60
|
+
* "@openzeppelin/=lib/openzeppelin-contracts/"
|
|
61
|
+
* This is from Uniswap's UniversalRouter in the Settings section after the source files
|
|
62
|
+
* https://etherscan.io/address/0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B#code
|
|
63
|
+
* @param mapping
|
|
64
|
+
*/
|
|
65
|
+
export declare const parseRemapping: (mapping: string) => Remapping;
|
package/lib/parserEtherscan.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.EtherscanParser = exports.networks = void 0;
|
|
6
|
+
exports.parseRemapping = exports.parseRemappings = exports.EtherscanParser = exports.networks = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const parser_1 = require("@solidity-parser/parser");
|
|
9
9
|
const converterAST2Classes_1 = require("./converterAST2Classes");
|
|
@@ -110,12 +110,12 @@ class EtherscanParser {
|
|
|
110
110
|
* @return Promise with an array of UmlClass objects
|
|
111
111
|
*/
|
|
112
112
|
async getUmlClasses(contractAddress) {
|
|
113
|
-
const { files, contractName } = await this.getSourceCode(contractAddress);
|
|
113
|
+
const { files, contractName, remappings } = await this.getSourceCode(contractAddress);
|
|
114
114
|
let umlClasses = [];
|
|
115
115
|
for (const file of files) {
|
|
116
116
|
debug(`Parsing source file ${file.filename}`);
|
|
117
117
|
const node = await this.parseSourceCode(file.code);
|
|
118
|
-
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename);
|
|
118
|
+
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename, remappings);
|
|
119
119
|
umlClasses = umlClasses.concat(umlClass);
|
|
120
120
|
}
|
|
121
121
|
return {
|
|
@@ -130,12 +130,12 @@ class EtherscanParser {
|
|
|
130
130
|
* @return Promise string of Solidity code
|
|
131
131
|
*/
|
|
132
132
|
async getSolidityCode(contractAddress) {
|
|
133
|
-
const { files, contractName, compilerVersion } = await this.getSourceCode(contractAddress);
|
|
133
|
+
const { files, contractName, compilerVersion, remappings } = await this.getSourceCode(contractAddress);
|
|
134
134
|
// Parse the UmlClasses from the Solidity code in each file
|
|
135
135
|
let umlClasses = [];
|
|
136
136
|
for (const file of files) {
|
|
137
137
|
const node = await this.parseSourceCode(file.code);
|
|
138
|
-
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename);
|
|
138
|
+
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, file.filename, remappings);
|
|
139
139
|
umlClasses = umlClasses.concat(umlClass);
|
|
140
140
|
}
|
|
141
141
|
// Sort the classes so dependent code is first
|
|
@@ -209,6 +209,7 @@ class EtherscanParser {
|
|
|
209
209
|
if (!Array.isArray(response?.data?.result)) {
|
|
210
210
|
throw new Error(`Failed to ${description}. No result array in HTTP data: ${JSON.stringify(response?.data)}`);
|
|
211
211
|
}
|
|
212
|
+
let remappings;
|
|
212
213
|
const results = response.data.result.map((result) => {
|
|
213
214
|
if (!result.SourceCode) {
|
|
214
215
|
throw new Error(`Failed to ${description}. Most likely the contract has not been verified on Etherscan.`);
|
|
@@ -223,6 +224,8 @@ class EtherscanParser {
|
|
|
223
224
|
parableResultString = result.SourceCode.slice(1, -1);
|
|
224
225
|
}
|
|
225
226
|
const sourceCodeObject = JSON.parse(parableResultString);
|
|
227
|
+
// Get any remapping of filenames from the settings
|
|
228
|
+
remappings = (0, exports.parseRemappings)(sourceCodeObject.settings?.remappings);
|
|
226
229
|
// The getsource response from Etherscan is inconsistent so we need to handle both shapes
|
|
227
230
|
const sourceFiles = sourceCodeObject.sources
|
|
228
231
|
? Object.entries(sourceCodeObject.sources)
|
|
@@ -239,6 +242,8 @@ class EtherscanParser {
|
|
|
239
242
|
// if multiple Solidity source files with no Etherscan bug in the SourceCode field
|
|
240
243
|
if (result?.SourceCode?.sources) {
|
|
241
244
|
const sourceFiles = Object.values(result.SourceCode.sources);
|
|
245
|
+
// Get any remapping of filenames from the settings
|
|
246
|
+
remappings = (0, exports.parseRemappings)(result.SourceCode.settings?.remappings);
|
|
242
247
|
return sourceFiles.map(([filename, code]) => ({
|
|
243
248
|
code: code.content,
|
|
244
249
|
filename,
|
|
@@ -254,6 +259,7 @@ class EtherscanParser {
|
|
|
254
259
|
files: results.flat(1),
|
|
255
260
|
contractName: response.data.result[0].ContractName,
|
|
256
261
|
compilerVersion: response.data.result[0].CompilerVersion,
|
|
262
|
+
remappings,
|
|
257
263
|
};
|
|
258
264
|
}
|
|
259
265
|
catch (err) {
|
|
@@ -268,4 +274,31 @@ class EtherscanParser {
|
|
|
268
274
|
}
|
|
269
275
|
}
|
|
270
276
|
exports.EtherscanParser = EtherscanParser;
|
|
277
|
+
/**
|
|
278
|
+
* Parses Ethersan's remappings config in its API response
|
|
279
|
+
* @param rawMappings
|
|
280
|
+
*/
|
|
281
|
+
const parseRemappings = (rawMappings) => {
|
|
282
|
+
if (!rawMappings)
|
|
283
|
+
return [];
|
|
284
|
+
return rawMappings.map((mapping) => (0, exports.parseRemapping)(mapping));
|
|
285
|
+
};
|
|
286
|
+
exports.parseRemappings = parseRemappings;
|
|
287
|
+
/**
|
|
288
|
+
* Parses a single mapping. For example
|
|
289
|
+
* "@openzeppelin/=lib/openzeppelin-contracts/"
|
|
290
|
+
* This is from Uniswap's UniversalRouter in the Settings section after the source files
|
|
291
|
+
* https://etherscan.io/address/0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B#code
|
|
292
|
+
* @param mapping
|
|
293
|
+
*/
|
|
294
|
+
const parseRemapping = (mapping) => {
|
|
295
|
+
const equalIndex = mapping.indexOf('=');
|
|
296
|
+
const from = mapping.slice(0, equalIndex);
|
|
297
|
+
const to = mapping.slice(equalIndex + 1);
|
|
298
|
+
return {
|
|
299
|
+
from: new RegExp('^' + from),
|
|
300
|
+
to,
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
exports.parseRemapping = parseRemapping;
|
|
271
304
|
//# sourceMappingURL=parserEtherscan.js.map
|
package/lib/parserFiles.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ASTNode } from '@solidity-parser/parser/dist/src/ast-types';
|
|
2
2
|
import { UmlClass } from './umlClass';
|
|
3
|
-
export declare const parseUmlClassesFromFiles: (filesOrFolders: string[], ignoreFilesOrFolders: string[], subfolders?: number) => Promise<UmlClass[]>;
|
|
4
|
-
export declare function getSolidityFilesFromFolderOrFiles(folderOrFilePaths: string[], ignoreFilesOrFolders: string[], subfolders?: number): Promise<string[]>;
|
|
5
|
-
export declare function getSolidityFilesFromFolderOrFile(folderOrFilePath: string, ignoreFilesOrFolders?: string[], depthLimit?: number): Promise<string[]>;
|
|
3
|
+
export declare const parseUmlClassesFromFiles: (filesOrFolders: readonly string[], ignoreFilesOrFolders: readonly string[], subfolders?: number) => Promise<UmlClass[]>;
|
|
4
|
+
export declare function getSolidityFilesFromFolderOrFiles(folderOrFilePaths: readonly string[], ignoreFilesOrFolders: readonly string[], subfolders?: number): Promise<string[]>;
|
|
5
|
+
export declare function getSolidityFilesFromFolderOrFile(folderOrFilePath: string, ignoreFilesOrFolders?: readonly string[], depthLimit?: number): Promise<string[]>;
|
|
6
6
|
export declare function parseSolidityFile(fileName: string): ASTNode;
|
package/lib/parserFiles.js
CHANGED
|
@@ -16,7 +16,7 @@ const parseUmlClassesFromFiles = async (filesOrFolders, ignoreFilesOrFolders, su
|
|
|
16
16
|
for (const file of files) {
|
|
17
17
|
const node = await parseSolidityFile(file);
|
|
18
18
|
const relativePath = (0, path_1.relative)(process.cwd(), file);
|
|
19
|
-
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, relativePath, true);
|
|
19
|
+
const umlClass = (0, converterAST2Classes_1.convertAST2UmlClasses)(node, relativePath, [], true);
|
|
20
20
|
umlClasses = umlClasses.concat(umlClass);
|
|
21
21
|
}
|
|
22
22
|
return umlClasses;
|
|
@@ -82,7 +82,7 @@ function getSolidityFilesFromFolderOrFile(folderOrFilePath, ignoreFilesOrFolders
|
|
|
82
82
|
else {
|
|
83
83
|
error = new Error(`Failed to get Solidity files under folder or file ${folderOrFilePath}`, { cause: err });
|
|
84
84
|
}
|
|
85
|
-
console.error(error
|
|
85
|
+
console.error(error);
|
|
86
86
|
reject(error);
|
|
87
87
|
}
|
|
88
88
|
});
|
package/lib/slotValues.d.ts
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
1
|
import { BigNumberish } from '@ethersproject/bignumber';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { StorageSection, Variable } from './converterClasses2Storage';
|
|
3
|
+
/**
|
|
4
|
+
* Adds the slot values to the variables in the storage section.
|
|
5
|
+
* This can be rerun for a section as it will only get if the slot value
|
|
6
|
+
* does not exist.
|
|
7
|
+
* @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
|
|
8
|
+
* @param contractAddress Contract address to get the storage slot values from.
|
|
9
|
+
* If contract is proxied, use proxy and not the implementation contract.
|
|
10
|
+
* @param storageSection is mutated with the slot values added to the variables
|
|
11
|
+
* @param arrayItems the number of items to display at the start and end of an array
|
|
12
|
+
* @param blockTag block number or `latest`
|
|
13
|
+
*/
|
|
14
|
+
export declare const addSlotValues: (url: string, contractAddress: string, storageSection: StorageSection, arrayItems: number, blockTag: BigNumberish) => Promise<void>;
|
|
15
|
+
export declare const parseValue: (variable: Variable) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Get storage slot values from JSON-RPC API provider.
|
|
18
|
+
* @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
|
|
19
|
+
* @param contractAddress Contract address to get the storage slot values from.
|
|
20
|
+
* If proxied, use proxy and not the implementation contract.
|
|
21
|
+
* @param slotKeys array of 32 byte slot keys as BigNumbers.
|
|
22
|
+
* @param blockTag block number or `latest`
|
|
23
|
+
* @return slotValues array of 32 byte slot values as hexadecimal strings
|
|
24
|
+
*/
|
|
25
|
+
export declare const getSlotValues: (url: string, contractAddress: string, slotKeys: readonly BigNumberish[], blockTag?: BigNumberish | 'latest') => Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Get storage slot values from JSON-RPC API provider.
|
|
28
|
+
* @param url of Ethereum JSON-RPC API provider. eg Infura or Alchemy
|
|
29
|
+
* @param contractAddress Contract address to get the storage slot values from.
|
|
30
|
+
* If proxied, use proxy and not the implementation contract.
|
|
31
|
+
* @param slotKey 32 byte slot key as a BigNumber.
|
|
32
|
+
* @param blockTag block number or `latest`
|
|
33
|
+
* @return slotValue 32 byte slot value as hexadecimal string
|
|
34
|
+
*/
|
|
35
|
+
export declare const getSlotValue: (url: string, contractAddress: string, slotKey: BigNumberish, blockTag: BigNumberish | 'latest') => Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Calculates the number of string characters or bytes of a string or bytes type.
|
|
38
|
+
* See the following for how string and bytes are stored in storage slots
|
|
39
|
+
* https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html#bytes-and-string
|
|
40
|
+
* @param variable the variable with the slotValue that is being sized
|
|
41
|
+
* @return bytes the number of bytes of the dynamic slot. If static, zero is return.
|
|
42
|
+
*/
|
|
43
|
+
export declare const dynamicSlotSize: (variable: {
|
|
44
|
+
name?: string;
|
|
45
|
+
type?: string;
|
|
46
|
+
slotValue?: string;
|
|
47
|
+
}) => number;
|
|
48
|
+
export declare const convert2String: (bytes: string) => string;
|
|
49
|
+
export declare const escapeString: (text: string) => string;
|