Skip to content

Commit

Permalink
Merge pull request trufflesuite#2107 from trufflesuite/switch-abi-ord…
Browse files Browse the repository at this point in the history
…ering-ast

Use current AST format instead of legacy for ordering ABI output
  • Loading branch information
gnidan authored Jun 18, 2019
2 parents e11f30c + 6223be9 commit ffde3b5
Showing 1 changed file with 28 additions and 61 deletions.
89 changes: 28 additions & 61 deletions packages/truffle-compile/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,72 +280,39 @@ function replaceLinkReferences(bytecode, linkReferences, libraryName) {
return bytecode;
}

function orderABI(contract) {
var contract_definition;
var ordered_function_names = [];

for (var i = 0; i < contract.legacyAST.children.length; i++) {
var definition = contract.legacyAST.children[i];

// AST can have multiple contract definitions, make sure we have the
// one that matches our contract
if (
definition.name !== "ContractDefinition" ||
definition.attributes.name !== contract.contract_name
) {
continue;
}
function orderABI({ abi, contract_name: contractName, ast }) {
// AST can have multiple contract definitions, make sure we have the
// one that matches our contract
const contractDefinition = ast.nodes.find(
({ nodeType, name }) =>
nodeType === "ContractDefinition" && name === contractName
);

contract_definition = definition;
break;
if (!contractDefinition || !contractDefinition.nodes) {
return abi;
}

if (!contract_definition) return contract.abi;
if (!contract_definition.children) return contract.abi;

contract_definition.children.forEach(function(child) {
if (child.name === "FunctionDefinition") {
ordered_function_names.push(child.attributes.name);
}
});
// Find all function definitions
const orderedFunctionNames = contractDefinition.nodes
.filter(({ nodeType }) => nodeType === "FunctionDefinition")
.map(({ name: functionName }) => functionName);

// Put function names in a hash with their order, lowest first, for speed.
var functions_to_remove = ordered_function_names.reduce(function(
obj,
value,
index
) {
obj[value] = index;
return obj;
},
{});

// Filter out functions from the abi
var function_definitions = contract.abi.filter(function(item) {
return functions_to_remove[item.name] !== undefined;
});

// Sort removed function defintions
function_definitions = function_definitions.sort(function(item_a, item_b) {
var a = functions_to_remove[item_a.name];
var b = functions_to_remove[item_b.name];

if (a > b) return 1;
if (a < b) return -1;
return 0;
});

// Create a new ABI, placing ordered functions at the end.
var newABI = [];
contract.abi.forEach(function(item) {
if (functions_to_remove[item.name] !== undefined) return;
newABI.push(item);
});

// Now pop the ordered functions definitions on to the end of the abi..
Array.prototype.push.apply(newABI, function_definitions);

return newABI;
const functionIndexes = orderedFunctionNames
.map((functionName, index) => ({ [functionName]: index }))
.reduce((a, b) => Object.assign({}, a, b), {});

// Construct new ABI with functions at the end in source order
return [
...abi.filter(({ name }) => functionIndexes[name] === undefined),

// followed by the functions in the source order
...abi
.filter(({ name }) => functionIndexes[name] !== undefined)
.sort(
({ name: a }, { name: b }) => functionIndexes[a] - functionIndexes[b]
)
];
}

// contracts_directory: String. Directory where .sol files can be found.
Expand Down

0 comments on commit ffde3b5

Please sign in to comment.