mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
FunctionCallGraph: operator<< for printing nodes in an unambiguous way
This commit is contained in:
parent
4c1f8d69f9
commit
74ef7dd790
@ -18,12 +18,16 @@
|
||||
|
||||
#include <libsolidity/analysis/FunctionCallGraph.h>
|
||||
|
||||
#include <libsolutil/StringUtils.h>
|
||||
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
#include <range/v3/view/reverse.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ranges;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::util;
|
||||
|
||||
bool FunctionCallGraphBuilder::CompareByID::operator()(Node const& _lhs, Node const& _rhs) const
|
||||
{
|
||||
@ -278,3 +282,62 @@ void FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _ca
|
||||
|
||||
enqueueCallable(_callable);
|
||||
}
|
||||
|
||||
ostream& solidity::frontend::operator<<(ostream& _out, FunctionCallGraphBuilder::Node const& _node)
|
||||
{
|
||||
using SpecialNode = FunctionCallGraphBuilder::SpecialNode;
|
||||
|
||||
if (holds_alternative<SpecialNode>(_node))
|
||||
switch (get<SpecialNode>(_node))
|
||||
{
|
||||
case SpecialNode::InternalDispatch:
|
||||
_out << "InternalDispatch";
|
||||
break;
|
||||
case SpecialNode::Entry:
|
||||
_out << "Entry";
|
||||
break;
|
||||
default: solAssert(false, "Invalid SpecialNode type");
|
||||
}
|
||||
else
|
||||
{
|
||||
solAssert(holds_alternative<CallableDeclaration const*>(_node), "");
|
||||
|
||||
auto const* callableDeclaration = get<CallableDeclaration const*>(_node);
|
||||
solAssert(callableDeclaration, "");
|
||||
|
||||
auto const* function = dynamic_cast<FunctionDefinition const *>(callableDeclaration);
|
||||
auto const* event = dynamic_cast<EventDefinition const *>(callableDeclaration);
|
||||
auto const* modifier = dynamic_cast<ModifierDefinition const *>(callableDeclaration);
|
||||
|
||||
auto typeToString = [](auto const& _var) -> string { return _var->type()->toString(true); };
|
||||
vector<string> parameters = callableDeclaration->parameters() | views::transform(typeToString) | to<vector<string>>();
|
||||
|
||||
string scopeName;
|
||||
if (!function || !function->isFree())
|
||||
{
|
||||
solAssert(callableDeclaration->annotation().scope, "");
|
||||
auto const* parentContract = dynamic_cast<ContractDefinition const*>(callableDeclaration->annotation().scope);
|
||||
solAssert(parentContract, "");
|
||||
scopeName = parentContract->name();
|
||||
}
|
||||
|
||||
if (function && function->isFree())
|
||||
_out << "function " << function->name() << "(" << joinHumanReadable(parameters, ",") << ")";
|
||||
else if (function && function->isConstructor())
|
||||
_out << "constructor of " << scopeName;
|
||||
else if (function && function->isFallback())
|
||||
_out << "fallback of " << scopeName;
|
||||
else if (function && function->isReceive())
|
||||
_out << "receive of " << scopeName;
|
||||
else if (function)
|
||||
_out << "function " << scopeName << "." << function->name() << "(" << joinHumanReadable(parameters, ",") << ")";
|
||||
else if (event)
|
||||
_out << "event " << scopeName << "." << event->name() << "(" << joinHumanReadable(parameters, ",") << ")";
|
||||
else if (modifier)
|
||||
_out << "modifier " << scopeName << "." << modifier->name();
|
||||
else
|
||||
solAssert(false, "Unexpected AST node type in function call graph");
|
||||
}
|
||||
|
||||
return _out;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
|
||||
#include <deque>
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
@ -119,4 +120,6 @@ private:
|
||||
std::deque<CallableDeclaration const*> m_visitQueue;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& _out, FunctionCallGraphBuilder::Node const& _node);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user