@gnus.ai/upgrade-safe-transpiler-diamond
Version:
Solidity preprocessor used to generate OpenZeppelin Contracts Upgrade Safe using Diamond Pattern (EIP-2535).
131 lines • 5.79 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNodeCount = exports.getScopedContractName = exports.getScopedContractsForVariables = exports.addVariableScopedContract = exports.getUniqueIdentifierVarsUsed = void 0;
const utils_1 = require("solidity-ast/utils");
const upgrades_overrides_1 = require("../../utils/upgrades-overrides");
const path_1 = __importDefault(require("path"));
const assert_1 = __importDefault(require("assert"));
function getUniqueIdentifierVarsUsed(contractNode, tools) {
const { resolver } = tools;
const identifiers = new Map();
const identifierNodes = (0, utils_1.findAll)('Identifier', contractNode);
for (const identifier of identifierNodes) {
const { id, referencedDeclaration } = identifier;
if (referencedDeclaration && !identifiers.has(id)) {
const varDecl = resolver.resolveNode('VariableDeclaration', referencedDeclaration, false);
if (varDecl && !varDecl.constant && varDecl.stateVariable &&
!(0, upgrades_overrides_1.hasOverride)(varDecl, 'state-variable-assignment') &&
!(0, upgrades_overrides_1.hasOverride)(varDecl, 'state-variable-immutable')) {
identifiers.set(id, { identifier, varDecl });
}
}
}
return identifiers;
}
exports.getUniqueIdentifierVarsUsed = getUniqueIdentifierVarsUsed;
function addScopedContract(referenceScopes, id, resolver) {
var _a, _b;
const nodeInfo = resolver.resolveScope(id);
if (nodeInfo) {
let contract = undefined;
if (((_a = nodeInfo.node) === null || _a === void 0 ? void 0 : _a.nodeType) === 'ContractDefinition') {
contract = nodeInfo.node;
}
else if (((_b = nodeInfo.scopeNode) === null || _b === void 0 ? void 0 : _b.nodeType) === 'ContractDefinition') {
contract = nodeInfo.scopeNode;
}
if (contract) {
if (!referenceScopes.has(nodeInfo.path)) {
referenceScopes.set(nodeInfo.path, new Set());
}
const contractNamesSet = referenceScopes.get(nodeInfo.path);
contractNamesSet.add(contract.name);
}
}
}
function addScopedContractTypeNames(referenceScopes, typeName, resolver) {
switch (typeName.nodeType) {
case 'UserDefinedTypeName':
addScopedContract(referenceScopes, typeName.referencedDeclaration, resolver);
break;
case 'ArrayTypeName':
addScopedContractTypeNames(referenceScopes, typeName.baseType, resolver);
break;
case 'FunctionTypeName':
addScopedContract(referenceScopes, typeName.id, resolver);
typeName.parameterTypes.parameters.forEach(varDecl => { addVariableScopedContract(referenceScopes, varDecl, resolver); });
typeName.returnParameterTypes.parameters.forEach(varDecl => { addVariableScopedContract(referenceScopes, varDecl, resolver); });
break;
case 'Mapping':
addScopedContractTypeNames(referenceScopes, typeName.keyType, resolver);
addScopedContractTypeNames(referenceScopes, typeName.valueType, resolver);
break;
case 'ElementaryTypeName':
break;
}
}
function addVariableScopedContract(referenceScopes, varDecl, resolver) {
addScopedContract(referenceScopes, varDecl.scope, resolver);
if (varDecl.typeName) {
addScopedContractTypeNames(referenceScopes, varDecl.typeName, resolver);
}
}
exports.addVariableScopedContract = addVariableScopedContract;
/**
* Get a set/map of unique types that are being referenced in the contract
* @param contractNode
* @param tools
*/
function getScopedContractsForVariables(contract, tools) {
const { resolver } = tools;
const referenceScopes = new Map();
for (const [_, idVar] of getUniqueIdentifierVarsUsed(contract, tools)) {
addScopedContract(referenceScopes, idVar.varDecl.id, resolver);
}
return referenceScopes;
}
exports.getScopedContractsForVariables = getScopedContractsForVariables;
function getScopedContractName(scope, contractPaths, contractScopes, tools, suffix = 'Storage') {
const { resolver } = tools;
let contractName = contractScopes.get(scope);
if (!contractName) {
const nodeInfo = resolver.resolveScope(scope);
(0, assert_1.default)(nodeInfo, `Unable to find scope for id: ${scope}`);
const { dir, name, ext } = path_1.default.parse(nodeInfo.path);
const contractPath = `${dir}/${name}${suffix}${ext}`;
if (nodeInfo.node.nodeType === 'ContractDefinition') {
contractName = nodeInfo.node.name + suffix;
contractScopes.set(scope, contractName);
if (!contractPaths.has(contractPath)) {
contractPaths.set(contractPath, new Set());
}
const contractSet = contractPaths.get(contractPath);
if (!contractSet.has(contractName)) {
contractSet.add(contractName);
}
}
else {
contractName = '';
}
}
return contractName;
}
exports.getScopedContractName = getScopedContractName;
function getNodeCount(nodeTypes, contract, filter) {
if (!Array.isArray(nodeTypes)) {
nodeTypes = [nodeTypes];
}
let count = 0;
contract.nodes.forEach(node => {
const newNode = node;
if ((nodeTypes.indexOf(newNode.nodeType) > -1) && (!filter || filter(newNode))) {
count++;
}
});
return count;
}
exports.getNodeCount = getNodeCount;
//# sourceMappingURL=get-identifiers-used.js.map