From 0e3ff25b4e5305bcca1addb1698a166d2297993f Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Mon, 19 Aug 2019 16:26:14 +0200 Subject: [PATCH] Make sure json output array order is consistent The source of the "contractDependencies" value was an std::map, thus order was more or less random. --- libsolidity/ast/ASTJsonConverter.cpp | 5 +- libsolidity/ast/ASTJsonConverter.h | 20 +- .../ASTJSON/contract_dep_order.json | 233 ++++++++++++++ .../ASTJSON/contract_dep_order.sol | 7 + .../ASTJSON/contract_dep_order_legacy.json | 288 ++++++++++++++++++ .../ASTJSON/inheritance_specifier.sol | 2 + 6 files changed, 549 insertions(+), 6 deletions(-) create mode 100644 test/libsolidity/ASTJSON/contract_dep_order.json create mode 100644 test/libsolidity/ASTJSON/contract_dep_order.sol create mode 100644 test/libsolidity/ASTJSON/contract_dep_order_legacy.json diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index d791a8a06..669b46d53 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -27,6 +27,9 @@ #include #include +#include +#include + using namespace std; using namespace langutil; @@ -259,7 +262,7 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node) make_pair("fullyImplemented", _node.annotation().unimplementedFunctions.empty()), make_pair("linearizedBaseContracts", getContainerIds(_node.annotation().linearizedBaseContracts)), make_pair("baseContracts", toJson(_node.baseContracts())), - make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies)), + make_pair("contractDependencies", getContainerIds(_node.annotation().contractDependencies, true)), make_pair("nodes", toJson(_node.subNodes())), make_pair("scope", idOrNull(_node.scope())) }); diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index abc84f813..7cd1dde39 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include namespace langutil { @@ -148,15 +150,23 @@ private: return _node.id(); } template - static Json::Value getContainerIds(Container const& container) + static Json::Value getContainerIds(Container const& _container, bool _order = false) { - Json::Value tmp(Json::arrayValue); - for (auto const& element: container) + std::vector tmp; + + for (auto const& element: _container) { solAssert(element, ""); - tmp.append(nodeId(*element)); + tmp.push_back(nodeId(*element)); } - return tmp; + if (_order) + std::sort(tmp.begin(), tmp.end()); + Json::Value json(Json::arrayValue); + + for (int val: tmp) + json.append(val); + + return json; } static Json::Value typePointerToJson(TypePointer _tp, bool _short = false); static Json::Value typePointerToJson(boost::optional const& _tps); diff --git a/test/libsolidity/ASTJSON/contract_dep_order.json b/test/libsolidity/ASTJSON/contract_dep_order.json new file mode 100644 index 000000000..de42ca600 --- /dev/null +++ b/test/libsolidity/ASTJSON/contract_dep_order.json @@ -0,0 +1,233 @@ +{ + "absolutePath" : "a", + "exportedSymbols" : + { + "A" : + [ + 1 + ], + "B" : + [ + 4 + ], + "C" : + [ + 7 + ], + "D" : + [ + 10 + ], + "E" : + [ + 13 + ] + }, + "id" : 14, + "nodeType" : "SourceUnit", + "nodes" : + [ + { + "baseContracts" : [], + "contractDependencies" : [], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 1, + "linearizedBaseContracts" : + [ + 1 + ], + "name" : "A", + "nodeType" : "ContractDefinition", + "nodes" : [], + "scope" : 14, + "src" : "0:14:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 2, + "name" : "A", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 1, + "src" : "29:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_A_$1", + "typeString" : "contract A" + } + }, + "id" : 3, + "nodeType" : "InheritanceSpecifier", + "src" : "29:1:1" + } + ], + "contractDependencies" : + [ + 1 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 4, + "linearizedBaseContracts" : + [ + 4, + 1 + ], + "name" : "B", + "nodeType" : "ContractDefinition", + "nodes" : [], + "scope" : 14, + "src" : "15:19:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 5, + "name" : "B", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 4, + "src" : "49:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_B_$4", + "typeString" : "contract B" + } + }, + "id" : 6, + "nodeType" : "InheritanceSpecifier", + "src" : "49:1:1" + } + ], + "contractDependencies" : + [ + 1, + 4 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 7, + "linearizedBaseContracts" : + [ + 7, + 4, + 1 + ], + "name" : "C", + "nodeType" : "ContractDefinition", + "nodes" : [], + "scope" : 14, + "src" : "35:19:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 8, + "name" : "C", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 7, + "src" : "69:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_C_$7", + "typeString" : "contract C" + } + }, + "id" : 9, + "nodeType" : "InheritanceSpecifier", + "src" : "69:1:1" + } + ], + "contractDependencies" : + [ + 1, + 4, + 7 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 10, + "linearizedBaseContracts" : + [ + 10, + 7, + 4, + 1 + ], + "name" : "D", + "nodeType" : "ContractDefinition", + "nodes" : [], + "scope" : 14, + "src" : "55:19:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 11, + "name" : "D", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 10, + "src" : "89:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_D_$10", + "typeString" : "contract D" + } + }, + "id" : 12, + "nodeType" : "InheritanceSpecifier", + "src" : "89:1:1" + } + ], + "contractDependencies" : + [ + 1, + 4, + 7, + 10 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 13, + "linearizedBaseContracts" : + [ + 13, + 10, + 7, + 4, + 1 + ], + "name" : "E", + "nodeType" : "ContractDefinition", + "nodes" : [], + "scope" : 14, + "src" : "75:19:1" + } + ], + "src" : "0:95:1" +} diff --git a/test/libsolidity/ASTJSON/contract_dep_order.sol b/test/libsolidity/ASTJSON/contract_dep_order.sol new file mode 100644 index 000000000..7558e01dc --- /dev/null +++ b/test/libsolidity/ASTJSON/contract_dep_order.sol @@ -0,0 +1,7 @@ +contract A { } +contract B is A { } +contract C is B { } +contract D is C { } +contract E is D { } + +// ---- diff --git a/test/libsolidity/ASTJSON/contract_dep_order_legacy.json b/test/libsolidity/ASTJSON/contract_dep_order_legacy.json new file mode 100644 index 000000000..5990b52ca --- /dev/null +++ b/test/libsolidity/ASTJSON/contract_dep_order_legacy.json @@ -0,0 +1,288 @@ +{ + "attributes" : + { + "absolutePath" : "a", + "exportedSymbols" : + { + "A" : + [ + 1 + ], + "B" : + [ + 4 + ], + "C" : + [ + 7 + ], + "D" : + [ + 10 + ], + "E" : + [ + 13 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "baseContracts" : + [ + null + ], + "contractDependencies" : + [ + null + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 1 + ], + "name" : "A", + "nodes" : + [ + null + ], + "scope" : 14 + }, + "id" : 1, + "name" : "ContractDefinition", + "src" : "0:14:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 1 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 4, + 1 + ], + "name" : "B", + "nodes" : + [ + null + ], + "scope" : 14 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "A", + "referencedDeclaration" : 1, + "type" : "contract A" + }, + "id" : 2, + "name" : "UserDefinedTypeName", + "src" : "29:1:1" + } + ], + "id" : 3, + "name" : "InheritanceSpecifier", + "src" : "29:1:1" + } + ], + "id" : 4, + "name" : "ContractDefinition", + "src" : "15:19:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 1, + 4 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 7, + 4, + 1 + ], + "name" : "C", + "nodes" : + [ + null + ], + "scope" : 14 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "B", + "referencedDeclaration" : 4, + "type" : "contract B" + }, + "id" : 5, + "name" : "UserDefinedTypeName", + "src" : "49:1:1" + } + ], + "id" : 6, + "name" : "InheritanceSpecifier", + "src" : "49:1:1" + } + ], + "id" : 7, + "name" : "ContractDefinition", + "src" : "35:19:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 1, + 4, + 7 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 10, + 7, + 4, + 1 + ], + "name" : "D", + "nodes" : + [ + null + ], + "scope" : 14 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "C", + "referencedDeclaration" : 7, + "type" : "contract C" + }, + "id" : 8, + "name" : "UserDefinedTypeName", + "src" : "69:1:1" + } + ], + "id" : 9, + "name" : "InheritanceSpecifier", + "src" : "69:1:1" + } + ], + "id" : 10, + "name" : "ContractDefinition", + "src" : "55:19:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 1, + 4, + 7, + 10 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 13, + 10, + 7, + 4, + 1 + ], + "name" : "E", + "nodes" : + [ + null + ], + "scope" : 14 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "D", + "referencedDeclaration" : 10, + "type" : "contract D" + }, + "id" : 11, + "name" : "UserDefinedTypeName", + "src" : "89:1:1" + } + ], + "id" : 12, + "name" : "InheritanceSpecifier", + "src" : "89:1:1" + } + ], + "id" : 13, + "name" : "ContractDefinition", + "src" : "75:19:1" + } + ], + "id" : 14, + "name" : "SourceUnit", + "src" : "0:95:1" +} diff --git a/test/libsolidity/ASTJSON/inheritance_specifier.sol b/test/libsolidity/ASTJSON/inheritance_specifier.sol index 02dbf0c51..0809cbe79 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier.sol +++ b/test/libsolidity/ASTJSON/inheritance_specifier.sol @@ -1 +1,3 @@ contract C1 {} contract C2 is C1 {} + +// ----