inheritanceOrdering.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. const path = require('path');
  2. const graphlib = require('graphlib');
  3. const { findAll } = require('solidity-ast/utils');
  4. const { _: artifacts } = require('yargs').argv;
  5. for (const artifact of artifacts) {
  6. const { output: solcOutput } = require(path.resolve(__dirname, '..', artifact));
  7. const graph = new graphlib.Graph({ directed: true });
  8. const names = {};
  9. const linearized = [];
  10. for (const source in solcOutput.contracts) {
  11. for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) {
  12. names[contractDef.id] = contractDef.name;
  13. linearized.push(contractDef.linearizedBaseContracts);
  14. contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => {
  15. graph.setEdge(c1, c2);
  16. }));
  17. }
  18. }
  19. graphlib.alg.findCycles(graph).forEach(([ c1, c2 ]) => {
  20. console.log(`Conflict between ${names[c1]} and ${names[c2]} detected in the following dependency chains:`);
  21. linearized
  22. .filter(chain => chain.includes(parseInt(c1)) && chain.includes(parseInt(c2)))
  23. .forEach(chain => {
  24. const comp = chain.indexOf(c1) < chain.indexOf(c2) ? '>' : '<';
  25. console.log(`- ${names[c1]} ${comp} ${names[c2]}: ${chain.reverse().map(id => names[id]).join(', ')}`);
  26. });
  27. process.exitCode = 1;
  28. });
  29. }
  30. if (!process.exitCode) {
  31. console.log('Contract ordering is consistent.');
  32. }