From 6f8fd309a2df3474b6a6c5d5d0cd600e1178536e Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Fri, 28 Jun 2019 16:14:31 +0200 Subject: [PATCH] Compile only requested sources and contracts --- Changelog.md | 1 + libsolidity/interface/CompilerStack.cpp | 27 ++++++++++++++++++---- libsolidity/interface/CompilerStack.h | 15 ++++++++---- libsolidity/interface/StandardCompiler.cpp | 13 +++++------ 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Changelog.md b/Changelog.md index 0855f466b..09762d32a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Language Features: Compiler Features: * eWasm: Highly experimental eWasm output using ``--ewasm`` in the commandline interface or output selection of ``ewasm.wast`` in standard-json. * Metadata: Update the swarm hash, changes ``bzzr0`` to ``bzzr1`` and urls to use ``bzz-raw://``. + * Standard JSON Interface: compile only selected sources and contracts. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 96e03fe3e..4e662464f 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -398,13 +398,29 @@ bool CompilerStack::parseAndAnalyze() return parse() && analyze(); } -bool CompilerStack::isRequestedContract(ContractDefinition const& _contract) const +bool CompilerStack::isRequestedSource(string const& _sourceName) const { return m_requestedContractNames.empty() || - m_requestedContractNames.count(_contract.fullyQualifiedName()) || - m_requestedContractNames.count(_contract.name()) || - m_requestedContractNames.count(":" + _contract.name()); + m_requestedContractNames.count("") || + m_requestedContractNames.count(_sourceName); +} + +bool CompilerStack::isRequestedContract(ContractDefinition const& _contract) const +{ + /// In case nothing was specified in outputSelection. + if (m_requestedContractNames.empty()) + return true; + + for (auto const& key: vector{"", _contract.sourceUnitName()}) + { + auto const& it = m_requestedContractNames.find(key); + if (it != m_requestedContractNames.end()) + if (it->second.count(_contract.name()) || it->second.count("")) + return true; + } + + return false; } bool CompilerStack::compile() @@ -900,7 +916,8 @@ void CompilerStack::resolveImports() }; for (auto const& sourcePair: m_sources) - toposort(&sourcePair.second); + if (isRequestedSource(sourcePair.first)) + toposort(&sourcePair.second); swap(m_sourceOrder, sourceOrder); } diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 153cff417..55df5d8f2 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -145,9 +146,12 @@ public: /// Must be set before parsing. void setEVMVersion(langutil::EVMVersion _version = langutil::EVMVersion{}); - /// Sets the list of requested contract names. If empty, no filtering is performed and every contract - /// found in the supplied sources is compiled. Names are cleared iff @a _contractNames is missing. - void setRequestedContractNames(std::set const& _contractNames = std::set{}) { + /// Sets the requested contract names by source. + /// If empty, no filtering is performed and every contract + /// found in the supplied sources is compiled. + /// Names are cleared iff @a _contractNames is missing. + void setRequestedContractNames(std::map> const& _contractNames = std::map>{}) + { m_requestedContractNames = _contractNames; } @@ -318,6 +322,9 @@ private: std::string applyRemapping(std::string const& _path, std::string const& _context); void resolveImports(); + /// @returns true if the source is requested to be compiled. + bool isRequestedSource(std::string const& _sourceName) const; + /// @returns true if the contract is requested to be compiled. bool isRequestedContract(ContractDefinition const& _contract) const; @@ -387,7 +394,7 @@ private: ReadCallback::Callback m_readFile; OptimiserSettings m_optimiserSettings; langutil::EVMVersion m_evmVersion; - std::set m_requestedContractNames; + std::map> m_requestedContractNames; bool m_generateIR; bool m_generateEWasm; std::map m_libraries; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index f34b5e836..fd23223d5 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -100,20 +100,19 @@ Json::Value formatErrorWithException( return formatError(_warning, _type, _component, message, formattedMessage, sourceLocation); } -set requestedContractNames(Json::Value const& _outputSelection) +map> requestedContractNames(Json::Value const& _outputSelection) { - set names; + map> contracts; for (auto const& sourceName: _outputSelection.getMemberNames()) { + string key = (sourceName == "*") ? "" : sourceName; for (auto const& contractName: _outputSelection[sourceName].getMemberNames()) { - /// Consider the "all sources" shortcuts as requesting everything. - if (contractName == "*" || contractName == "") - return set(); - names.insert((sourceName == "*" ? "" : sourceName) + ":" + contractName); + string value = (contractName == "*") ? "" : contractName; + contracts[key].insert(value); } } - return names; + return contracts; } /// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content.