mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move CallGraph structure to a separate module
This commit is contained in:
parent
769a7687c6
commit
6c28120f19
@ -56,6 +56,8 @@ set(sources
|
||||
ast/ASTJsonImporter.cpp
|
||||
ast/ASTJsonImporter.h
|
||||
ast/ASTVisitor.h
|
||||
ast/CallGraph.cpp
|
||||
ast/CallGraph.h
|
||||
ast/ExperimentalFeatures.h
|
||||
ast/Types.cpp
|
||||
ast/Types.h
|
||||
|
@ -29,41 +29,17 @@ using namespace ranges;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::util;
|
||||
|
||||
bool FunctionCallGraphBuilder::CompareByID::operator()(Node const& _lhs, Node const& _rhs) const
|
||||
{
|
||||
if (_lhs.index() != _rhs.index())
|
||||
return _lhs.index() < _rhs.index();
|
||||
|
||||
if (holds_alternative<SpecialNode>(_lhs))
|
||||
return get<SpecialNode>(_lhs) < get<SpecialNode>(_rhs);
|
||||
return get<CallableDeclaration const*>(_lhs)->id() < get<CallableDeclaration const*>(_rhs)->id();
|
||||
}
|
||||
|
||||
bool FunctionCallGraphBuilder::CompareByID::operator()(Node const& _lhs, int64_t _rhs) const
|
||||
{
|
||||
solAssert(!holds_alternative<SpecialNode>(_lhs), "");
|
||||
|
||||
return get<CallableDeclaration const*>(_lhs)->id() < _rhs;
|
||||
}
|
||||
|
||||
bool FunctionCallGraphBuilder::CompareByID::operator()(int64_t _lhs, Node const& _rhs) const
|
||||
{
|
||||
solAssert(!holds_alternative<SpecialNode>(_rhs), "");
|
||||
|
||||
return _lhs < get<CallableDeclaration const*>(_rhs)->id();
|
||||
}
|
||||
|
||||
FunctionCallGraphBuilder::ContractCallGraph FunctionCallGraphBuilder::buildCreationGraph(ContractDefinition const& _contract)
|
||||
CallGraph FunctionCallGraphBuilder::buildCreationGraph(ContractDefinition const& _contract)
|
||||
{
|
||||
FunctionCallGraphBuilder builder(_contract);
|
||||
solAssert(builder.m_currentNode == Node(SpecialNode::Entry), "");
|
||||
solAssert(builder.m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), "");
|
||||
|
||||
// Create graph for constructor, state vars, etc
|
||||
for (ContractDefinition const* base: _contract.annotation().linearizedBaseContracts | views::reverse)
|
||||
{
|
||||
// The constructor and functions called in state variable initial assignments should have
|
||||
// an edge from Entry
|
||||
builder.m_currentNode = SpecialNode::Entry;
|
||||
builder.m_currentNode = CallGraph::SpecialNode::Entry;
|
||||
for (auto const* stateVar: base->stateVariables())
|
||||
stateVar->accept(builder);
|
||||
|
||||
@ -82,21 +58,21 @@ FunctionCallGraphBuilder::ContractCallGraph FunctionCallGraphBuilder::buildCreat
|
||||
inheritanceSpecifier->accept(builder);
|
||||
}
|
||||
|
||||
builder.m_currentNode = SpecialNode::Entry;
|
||||
builder.m_currentNode = CallGraph::SpecialNode::Entry;
|
||||
builder.processQueue();
|
||||
|
||||
return move(builder.m_graph);
|
||||
}
|
||||
|
||||
FunctionCallGraphBuilder::ContractCallGraph FunctionCallGraphBuilder::buildDeployedGraph(
|
||||
CallGraph FunctionCallGraphBuilder::buildDeployedGraph(
|
||||
ContractDefinition const& _contract,
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _creationGraph
|
||||
CallGraph const& _creationGraph
|
||||
)
|
||||
{
|
||||
solAssert(&_creationGraph.contract == &_contract, "");
|
||||
|
||||
FunctionCallGraphBuilder builder(_contract);
|
||||
solAssert(builder.m_currentNode == Node(SpecialNode::Entry), "");
|
||||
solAssert(builder.m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), "");
|
||||
|
||||
auto getSecondElement = [](auto const& _tuple){ return get<1>(_tuple); };
|
||||
|
||||
@ -121,17 +97,17 @@ FunctionCallGraphBuilder::ContractCallGraph FunctionCallGraphBuilder::buildDeplo
|
||||
|
||||
// All functions present in internal dispatch at creation time could potentially be pointers
|
||||
// assigned to state variables and as such may be reachable after deployment as well.
|
||||
builder.m_currentNode = SpecialNode::InternalDispatch;
|
||||
for (Node const& dispatchTarget: valueOrDefault(_creationGraph.edges, SpecialNode::InternalDispatch, {}))
|
||||
builder.m_currentNode = CallGraph::SpecialNode::InternalDispatch;
|
||||
for (CallGraph::Node const& dispatchTarget: valueOrDefault(_creationGraph.edges, CallGraph::SpecialNode::InternalDispatch, {}))
|
||||
{
|
||||
solAssert(!holds_alternative<SpecialNode>(dispatchTarget), "");
|
||||
solAssert(!holds_alternative<CallGraph::SpecialNode>(dispatchTarget), "");
|
||||
solAssert(get<CallableDeclaration const*>(dispatchTarget) != nullptr, "");
|
||||
|
||||
// Visit the callable to add not only it but also everything it calls too
|
||||
builder.functionReferenced(*get<CallableDeclaration const*>(dispatchTarget), false);
|
||||
}
|
||||
|
||||
builder.m_currentNode = SpecialNode::Entry;
|
||||
builder.m_currentNode = CallGraph::SpecialNode::Entry;
|
||||
builder.processQueue();
|
||||
|
||||
return move(builder.m_graph);
|
||||
@ -149,7 +125,7 @@ bool FunctionCallGraphBuilder::visit(FunctionCall const& _functionCall)
|
||||
// If it's not a direct call, we don't really know which function will be called (it may even
|
||||
// change at runtime). All we can do is to add an edge to the dispatch which in turn has
|
||||
// edges to all functions could possibly be called.
|
||||
add(m_currentNode, SpecialNode::InternalDispatch);
|
||||
add(m_currentNode, CallGraph::SpecialNode::InternalDispatch);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -241,13 +217,13 @@ void FunctionCallGraphBuilder::enqueueCallable(CallableDeclaration const& _calla
|
||||
m_visitQueue.push_back(&_callable);
|
||||
|
||||
// Insert the callable to the graph (with no edges coming out of it) to mark it as visited.
|
||||
m_graph.edges.insert({Node(&_callable), {}});
|
||||
m_graph.edges.insert({CallGraph::Node(&_callable), {}});
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionCallGraphBuilder::processQueue()
|
||||
{
|
||||
solAssert(m_currentNode == Node(SpecialNode::Entry), "Visit queue is already being processed.");
|
||||
solAssert(m_currentNode == CallGraph::Node(CallGraph::SpecialNode::Entry), "Visit queue is already being processed.");
|
||||
|
||||
while (!m_visitQueue.empty())
|
||||
{
|
||||
@ -258,10 +234,10 @@ void FunctionCallGraphBuilder::processQueue()
|
||||
get<CallableDeclaration const*>(m_currentNode)->accept(*this);
|
||||
}
|
||||
|
||||
m_currentNode = SpecialNode::Entry;
|
||||
m_currentNode = CallGraph::SpecialNode::Entry;
|
||||
}
|
||||
|
||||
void FunctionCallGraphBuilder::add(Node _caller, Node _callee)
|
||||
void FunctionCallGraphBuilder::add(CallGraph::Node _caller, CallGraph::Node _callee)
|
||||
{
|
||||
m_graph.edges[_caller].insert(_callee);
|
||||
}
|
||||
@ -271,29 +247,27 @@ void FunctionCallGraphBuilder::functionReferenced(CallableDeclaration const& _ca
|
||||
if (_calledDirectly)
|
||||
{
|
||||
solAssert(
|
||||
holds_alternative<SpecialNode>(m_currentNode) || m_graph.edges.count(m_currentNode) > 0,
|
||||
holds_alternative<CallGraph::SpecialNode>(m_currentNode) || m_graph.edges.count(m_currentNode) > 0,
|
||||
"Adding an edge from a node that has not been visited yet."
|
||||
);
|
||||
|
||||
add(m_currentNode, &_callable);
|
||||
}
|
||||
else
|
||||
add(SpecialNode::InternalDispatch, &_callable);
|
||||
add(CallGraph::SpecialNode::InternalDispatch, &_callable);
|
||||
|
||||
enqueueCallable(_callable);
|
||||
}
|
||||
|
||||
ostream& solidity::frontend::operator<<(ostream& _out, FunctionCallGraphBuilder::Node const& _node)
|
||||
ostream& solidity::frontend::operator<<(ostream& _out, CallGraph::Node const& _node)
|
||||
{
|
||||
using SpecialNode = FunctionCallGraphBuilder::SpecialNode;
|
||||
|
||||
if (holds_alternative<SpecialNode>(_node))
|
||||
switch (get<SpecialNode>(_node))
|
||||
if (holds_alternative<CallGraph::SpecialNode>(_node))
|
||||
switch (get<CallGraph::SpecialNode>(_node))
|
||||
{
|
||||
case SpecialNode::InternalDispatch:
|
||||
case CallGraph::SpecialNode::InternalDispatch:
|
||||
_out << "InternalDispatch";
|
||||
break;
|
||||
case SpecialNode::Entry:
|
||||
case CallGraph::SpecialNode::Entry:
|
||||
_out << "Entry";
|
||||
break;
|
||||
default: solAssert(false, "Invalid SpecialNode type");
|
||||
|
@ -20,18 +20,16 @@
|
||||
|
||||
#include <libsolidity/ast/ASTForward.h>
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
#include <libsolidity/ast/CallGraph.h>
|
||||
|
||||
#include <deque>
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates a Function call graph for a contract at the granularity of Solidity
|
||||
* functions and modifiers. The graph can represent the situation either at contract creation
|
||||
* Creates a function call graph for a contract at the granularity of Solidity functions and modifiers.
|
||||
* or after deployment. The graph does not preserve temporal relations between calls - edges
|
||||
* coming out of the same node show which calls were performed but not in what order.
|
||||
*
|
||||
@ -59,43 +57,10 @@ namespace solidity::frontend
|
||||
class FunctionCallGraphBuilder: private ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
enum class SpecialNode
|
||||
{
|
||||
InternalDispatch,
|
||||
Entry,
|
||||
};
|
||||
|
||||
using Node = std::variant<CallableDeclaration const*, SpecialNode>;
|
||||
|
||||
struct CompareByID
|
||||
{
|
||||
using is_transparent = void;
|
||||
bool operator()(Node const& _lhs, Node const& _rhs) const;
|
||||
bool operator()(Node const& _lhs, int64_t _rhs) const;
|
||||
bool operator()(int64_t _lhs, Node const& _rhs) const;
|
||||
};
|
||||
|
||||
struct ContractCallGraph
|
||||
{
|
||||
/// Contract for which this is the graph
|
||||
ContractDefinition const& contract;
|
||||
|
||||
/// Graph edges. Edges are directed and lead from the caller to the callee.
|
||||
/// The map contains a key for every possible caller, even if does not actually perform
|
||||
/// any calls.
|
||||
std::map<Node, std::set<Node, CompareByID>, CompareByID> edges;
|
||||
|
||||
/// Contracts that may get created with `new` by functions present in the graph.
|
||||
std::set<ContractDefinition const*, ASTNode::CompareByID> createdContracts;
|
||||
|
||||
/// Events that may get emitted by functions present in the graph.
|
||||
std::set<EventDefinition const*, ASTNode::CompareByID> emittedEvents;
|
||||
};
|
||||
|
||||
static ContractCallGraph buildCreationGraph(ContractDefinition const& _contract);
|
||||
static ContractCallGraph buildDeployedGraph(
|
||||
static CallGraph buildCreationGraph(ContractDefinition const& _contract);
|
||||
static CallGraph buildDeployedGraph(
|
||||
ContractDefinition const& _contract,
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _creationGraph
|
||||
CallGraph const& _creationGraph
|
||||
);
|
||||
|
||||
private:
|
||||
@ -112,14 +77,14 @@ private:
|
||||
void enqueueCallable(CallableDeclaration const& _callable);
|
||||
void processQueue();
|
||||
|
||||
void add(Node _caller, Node _callee);
|
||||
void add(CallGraph::Node _caller, CallGraph::Node _callee);
|
||||
void functionReferenced(CallableDeclaration const& _callable, bool _calledDirectly = true);
|
||||
|
||||
Node m_currentNode = SpecialNode::Entry;
|
||||
ContractCallGraph m_graph;
|
||||
CallGraph::Node m_currentNode = CallGraph::SpecialNode::Entry;
|
||||
CallGraph m_graph;
|
||||
std::deque<CallableDeclaration const*> m_visitQueue;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& _out, FunctionCallGraphBuilder::Node const& _node);
|
||||
std::ostream& operator<<(std::ostream& _out, CallGraph::Node const& _node);
|
||||
|
||||
}
|
||||
|
46
libsolidity/ast/CallGraph.cpp
Normal file
46
libsolidity/ast/CallGraph.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include <libsolidity/ast/CallGraph.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
bool CallGraph::CompareByID::operator()(Node const& _lhs, Node const& _rhs) const
|
||||
{
|
||||
if (_lhs.index() != _rhs.index())
|
||||
return _lhs.index() < _rhs.index();
|
||||
|
||||
if (holds_alternative<SpecialNode>(_lhs))
|
||||
return get<SpecialNode>(_lhs) < get<SpecialNode>(_rhs);
|
||||
return get<CallableDeclaration const*>(_lhs)->id() < get<CallableDeclaration const*>(_rhs)->id();
|
||||
}
|
||||
|
||||
bool CallGraph::CompareByID::operator()(Node const& _lhs, int64_t _rhs) const
|
||||
{
|
||||
solAssert(!holds_alternative<SpecialNode>(_lhs), "");
|
||||
|
||||
return get<CallableDeclaration const*>(_lhs)->id() < _rhs;
|
||||
}
|
||||
|
||||
bool CallGraph::CompareByID::operator()(int64_t _lhs, Node const& _rhs) const
|
||||
{
|
||||
solAssert(!holds_alternative<SpecialNode>(_rhs), "");
|
||||
|
||||
return _lhs < get<CallableDeclaration const*>(_rhs)->id();
|
||||
}
|
74
libsolidity/ast/CallGraph.h
Normal file
74
libsolidity/ast/CallGraph.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
/// Data structure representing a function call graph.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/ast/AST.h>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <variant>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
|
||||
/**
|
||||
* Function call graph for a contract at the granularity of Solidity functions and modifiers.
|
||||
* The graph can represent the situation either at contract creation or after deployment.
|
||||
* The graph does not preserve temporal relations between calls - edges coming out of the same node
|
||||
* show which calls were performed but not in what order.
|
||||
*
|
||||
* Stores also extra information about contracts that can be created and events that can be emitted
|
||||
* from any of the functions in it.
|
||||
*/
|
||||
struct CallGraph
|
||||
{
|
||||
enum class SpecialNode
|
||||
{
|
||||
InternalDispatch,
|
||||
Entry,
|
||||
};
|
||||
|
||||
using Node = std::variant<CallableDeclaration const*, SpecialNode>;
|
||||
|
||||
struct CompareByID
|
||||
{
|
||||
using is_transparent = void;
|
||||
bool operator()(Node const& _lhs, Node const& _rhs) const;
|
||||
bool operator()(Node const& _lhs, int64_t _rhs) const;
|
||||
bool operator()(int64_t _lhs, Node const& _rhs) const;
|
||||
};
|
||||
|
||||
/// Contract for which this is the graph
|
||||
ContractDefinition const& contract;
|
||||
|
||||
/// Graph edges. Edges are directed and lead from the caller to the callee.
|
||||
/// The map contains a key for every possible caller, even if does not actually perform
|
||||
/// any calls.
|
||||
std::map<Node, std::set<Node, CompareByID>, CompareByID> edges;
|
||||
|
||||
/// Contracts that may get created with `new` by functions present in the graph.
|
||||
std::set<ContractDefinition const*, ASTNode::CompareByID> createdContracts;
|
||||
|
||||
/// Events that may get emitted by functions present in the graph.
|
||||
std::set<EventDefinition const*, ASTNode::CompareByID> emittedEvents;
|
||||
};
|
||||
|
||||
}
|
@ -78,11 +78,11 @@ void verifyCallGraph(
|
||||
}
|
||||
|
||||
set<CallableDeclaration const*, ASTNode::CompareByID> collectReachableCallables(
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _graph
|
||||
CallGraph const& _graph
|
||||
)
|
||||
{
|
||||
set<CallableDeclaration const*, ASTNode::CompareByID> reachableCallables;
|
||||
for (FunctionCallGraphBuilder::Node const& reachableNode: _graph.edges | views::keys)
|
||||
for (CallGraph::Node const& reachableNode: _graph.edges | views::keys)
|
||||
if (holds_alternative<CallableDeclaration const*>(reachableNode))
|
||||
reachableCallables.emplace(get<CallableDeclaration const*>(reachableNode));
|
||||
|
||||
@ -119,10 +119,7 @@ pair<string, string> IRGenerator::run(
|
||||
return {warning + ir, warning + asmStack.print()};
|
||||
}
|
||||
|
||||
void IRGenerator::verifyCallGraphs(
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _creationGraph,
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _deployedGraph
|
||||
)
|
||||
void IRGenerator::verifyCallGraphs(CallGraph const& _creationGraph, CallGraph const& _deployedGraph)
|
||||
{
|
||||
// m_creationFunctionList and m_deployedFunctionList are not used for any other purpose so
|
||||
// we can just destroy them without bothering to make a copy.
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
#include <libsolidity/ast/ASTForward.h>
|
||||
#include <libsolidity/analysis/FunctionCallGraph.h>
|
||||
#include <libsolidity/ast/CallGraph.h>
|
||||
#include <libsolidity/codegen/ir/IRGenerationContext.h>
|
||||
#include <libsolidity/codegen/YulUtilFunctions.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
@ -57,10 +57,7 @@ public:
|
||||
std::map<ContractDefinition const*, std::string_view const> const& _otherYulSources
|
||||
);
|
||||
|
||||
void verifyCallGraphs(
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _creationGraph,
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& _deployedGraph
|
||||
);
|
||||
void verifyCallGraphs(CallGraph const& _creationGraph, CallGraph const& _deployedGraph);
|
||||
|
||||
private:
|
||||
std::string generate(
|
||||
|
@ -950,7 +950,7 @@ string const& CompilerStack::metadata(Contract const& _contract) const
|
||||
return _contract.metadata.init([&]{ return createMetadata(_contract); });
|
||||
}
|
||||
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& CompilerStack::creationCallGraph(string const& _contractName) const
|
||||
CallGraph const& CompilerStack::creationCallGraph(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Analysis was not successful."));
|
||||
@ -959,7 +959,7 @@ FunctionCallGraphBuilder::ContractCallGraph const& CompilerStack::creationCallGr
|
||||
return contract(_contractName).creationCallGraph.value();
|
||||
}
|
||||
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& CompilerStack::deployedCallGraph(string const& _contractName) const
|
||||
CallGraph const& CompilerStack::deployedCallGraph(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Analysis was not successful."));
|
||||
|
@ -348,10 +348,10 @@ public:
|
||||
Json::Value gasEstimates(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a graph with edges representing calls between functions that may happen during contract construction.
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& creationCallGraph(std::string const& _contractName) const;
|
||||
CallGraph const& creationCallGraph(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a graph with edges representing calls between functions that may happen in a deployed contract.
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& deployedCallGraph(std::string const& _contractName) const;
|
||||
CallGraph const& deployedCallGraph(std::string const& _contractName) const;
|
||||
|
||||
/// Changes the format of the metadata appended at the end of the bytecode.
|
||||
/// This is mostly a workaround to avoid bytecode and gas differences between compiler builds
|
||||
@ -394,8 +394,8 @@ private:
|
||||
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
||||
mutable std::optional<std::string const> sourceMapping;
|
||||
mutable std::optional<std::string const> runtimeSourceMapping;
|
||||
std::optional<FunctionCallGraphBuilder::ContractCallGraph const> creationCallGraph;
|
||||
std::optional<FunctionCallGraphBuilder::ContractCallGraph const> deployedCallGraph;
|
||||
std::optional<CallGraph const> creationCallGraph;
|
||||
std::optional<CallGraph const> deployedCallGraph;
|
||||
};
|
||||
|
||||
/// Loads the missing sources from @a _ast (named @a _path) using the callback
|
||||
|
@ -53,12 +53,12 @@ using namespace solidity::langutil;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
using EdgeMap = map<
|
||||
FunctionCallGraphBuilder::Node,
|
||||
set<FunctionCallGraphBuilder::Node, FunctionCallGraphBuilder::CompareByID>,
|
||||
FunctionCallGraphBuilder::CompareByID
|
||||
CallGraph::Node,
|
||||
set<CallGraph::Node, CallGraph::CompareByID>,
|
||||
CallGraph::CompareByID
|
||||
>;
|
||||
using EdgeNames = set<tuple<string, string>>;
|
||||
using CallGraphMap = map<string, FunctionCallGraphBuilder::ContractCallGraph const*>;
|
||||
using CallGraphMap = map<string, CallGraph const*>;
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -131,7 +131,7 @@ void checkCallGraphExpectations(
|
||||
)
|
||||
{
|
||||
auto getContractName = [](ContractDefinition const* _contract){ return _contract->name(); };
|
||||
auto eventToString = [](EventDefinition const* _event){ return toString(FunctionCallGraphBuilder::Node(_event)); };
|
||||
auto eventToString = [](EventDefinition const* _event){ return toString(CallGraph::Node(_event)); };
|
||||
auto notEmpty = [](set<string> const& _set){ return !_set.empty(); };
|
||||
|
||||
soltestAssert(
|
||||
@ -157,7 +157,7 @@ void checkCallGraphExpectations(
|
||||
for (string const& contractName: _expectedEdges | views::keys)
|
||||
{
|
||||
soltestAssert(_callGraphs.at(contractName) != nullptr, "");
|
||||
FunctionCallGraphBuilder::ContractCallGraph const& callGraph = *_callGraphs.at(contractName);
|
||||
CallGraph const& callGraph = *_callGraphs.at(contractName);
|
||||
|
||||
edges[contractName] = edgeNames(callGraph.edges);
|
||||
if (!callGraph.createdContracts.empty())
|
||||
|
Loading…
Reference in New Issue
Block a user