aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/interface
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/interface')
-rw-r--r--libsolidity/interface/CompilerStack.cpp98
-rw-r--r--libsolidity/interface/CompilerStack.h112
-rw-r--r--libsolidity/interface/ErrorReporter.cpp14
-rw-r--r--libsolidity/interface/ErrorReporter.h22
-rw-r--r--libsolidity/interface/Exceptions.cpp13
-rw-r--r--libsolidity/interface/Natspec.cpp17
-rw-r--r--libsolidity/interface/Natspec.h10
-rw-r--r--libsolidity/interface/StandardCompiler.cpp73
8 files changed, 170 insertions, 189 deletions
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index e2507821..9689b700 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -87,6 +87,7 @@ void CompilerStack::reset(bool _keepSources)
m_stackState = Empty;
m_sources.clear();
}
+ m_libraries.clear();
m_optimize = false;
m_optimizeRuns = 200;
m_globalContext.reset();
@@ -106,12 +107,6 @@ bool CompilerStack::addSource(string const& _name, string const& _content, bool
return existed;
}
-void CompilerStack::setSource(string const& _sourceCode)
-{
- reset();
- addSource("", _sourceCode);
-}
-
bool CompilerStack::parse()
{
//reset
@@ -252,44 +247,17 @@ bool CompilerStack::analyze()
return false;
}
-bool CompilerStack::parse(string const& _sourceCode)
-{
- setSource(_sourceCode);
- return parse();
-}
-
bool CompilerStack::parseAndAnalyze()
{
return parse() && analyze();
}
-bool CompilerStack::parseAndAnalyze(std::string const& _sourceCode)
-{
- setSource(_sourceCode);
- return parseAndAnalyze();
-}
-
-vector<string> CompilerStack::contractNames() const
-{
- if (m_stackState < AnalysisSuccessful)
- BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
- vector<string> contractNames;
- for (auto const& contract: m_contracts)
- contractNames.push_back(contract.first);
- return contractNames;
-}
-
-
-bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> const& _libraries)
+bool CompilerStack::compile()
{
if (m_stackState < AnalysisSuccessful)
if (!parseAndAnalyze())
return false;
- m_optimize = _optimize;
- m_optimizeRuns = _runs;
- m_libraries = _libraries;
-
map<ContractDefinition const*, eth::Assembly const*> compiledContracts;
for (Source const* source: m_sourceOrder)
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
@@ -300,11 +268,6 @@ bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> co
return true;
}
-bool CompilerStack::compile(string const& _sourceCode, bool _optimize, unsigned _runs)
-{
- return parseAndAnalyze(_sourceCode) && compile(_optimize, _runs);
-}
-
void CompilerStack::link()
{
for (auto& contract: m_contracts)
@@ -315,6 +278,16 @@ void CompilerStack::link()
}
}
+vector<string> CompilerStack::contractNames() const
+{
+ if (m_stackState < AnalysisSuccessful)
+ BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
+ vector<string> contractNames;
+ for (auto const& contract: m_contracts)
+ contractNames.push_back(contract.first);
+ return contractNames;
+}
+
eth::AssemblyItems const* CompilerStack::assemblyItems(string const& _contractName) const
{
Contract const& currentContract = contract(_contractName);
@@ -451,18 +424,20 @@ Json::Value const& CompilerStack::natspec(Contract const& _contract, Documentati
{
case DocumentationType::NatspecUser:
doc = &_contract.userDocumentation;
+ // caches the result
+ if (!*doc)
+ doc->reset(new Json::Value(Natspec::userDocumentation(*_contract.contract)));
break;
case DocumentationType::NatspecDev:
doc = &_contract.devDocumentation;
+ // caches the result
+ if (!*doc)
+ doc->reset(new Json::Value(Natspec::devDocumentation(*_contract.contract)));
break;
default:
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
+ solAssert(false, "Illegal documentation type.");
}
- // caches the result
- if (!*doc)
- doc->reset(new Json::Value(Natspec::documentation(*_contract.contract, _type)));
-
return *(*doc);
}
@@ -474,12 +449,12 @@ Json::Value CompilerStack::methodIdentifiers(string const& _contractName) const
return methodIdentifiers;
}
-string const& CompilerStack::onChainMetadata(string const& _contractName) const
+string const& CompilerStack::metadata(string const& _contractName) const
{
if (m_stackState != CompilationSuccessful)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful."));
- return contract(_contractName).onChainMetadata;
+ return contract(_contractName).metadata;
}
Scanner const& CompilerStack::scanner(string const& _sourceName) const
@@ -673,11 +648,11 @@ void CompilerStack::compileContract(
shared_ptr<Compiler> compiler = make_shared<Compiler>(m_optimize, m_optimizeRuns);
Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName());
- string onChainMetadata = createOnChainMetadata(compiledContract);
+ string metadata = createMetadata(compiledContract);
bytes cborEncodedMetadata =
- // CBOR-encoding of {"bzzr0": dev::swarmHash(onChainMetadata)}
+ // CBOR-encoding of {"bzzr0": dev::swarmHash(metadata)}
bytes{0xa1, 0x65, 'b', 'z', 'z', 'r', '0', 0x58, 0x20} +
- dev::swarmHash(onChainMetadata).asBytes();
+ dev::swarmHash(metadata).asBytes();
solAssert(cborEncodedMetadata.size() <= 0xffff, "Metadata too large");
// 16-bit big endian length
cborEncodedMetadata += toCompactBigEndian(cborEncodedMetadata.size(), 2);
@@ -690,11 +665,11 @@ void CompilerStack::compileContract(
}
catch(eth::OptimizerException const&)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Assembly optimizer exception for bytecode"));
+ solAssert(false, "Assembly optimizer exception for bytecode");
}
catch(eth::AssemblyException const&)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Assembly exception for bytecode"));
+ solAssert(false, "Assembly exception for bytecode");
}
try
@@ -703,14 +678,14 @@ void CompilerStack::compileContract(
}
catch(eth::OptimizerException const&)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Assembly optimizer exception for deployed bytecode"));
+ solAssert(false, "Assembly optimizer exception for deployed bytecode");
}
catch(eth::AssemblyException const&)
{
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Assembly exception for deployed bytecode"));
+ solAssert(false, "Assembly exception for deployed bytecode");
}
- compiledContract.onChainMetadata = onChainMetadata;
+ compiledContract.metadata = metadata;
_compiledContracts[compiledContract.contract] = &compiler->assembly();
try
@@ -771,16 +746,25 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co
return it->second;
}
-string CompilerStack::createOnChainMetadata(Contract const& _contract) const
+string CompilerStack::createMetadata(Contract const& _contract) const
{
Json::Value meta;
meta["version"] = 1;
meta["language"] = "Solidity";
meta["compiler"]["version"] = VersionStringStrict;
+ /// All the source files (including self), which should be included in the metadata.
+ set<string> referencedSources;
+ referencedSources.insert(_contract.contract->sourceUnit().annotation().path);
+ for (auto const sourceUnit: _contract.contract->sourceUnit().referencedSourceUnits(true))
+ referencedSources.insert(sourceUnit->annotation().path);
+
meta["sources"] = Json::objectValue;
for (auto const& s: m_sources)
{
+ if (!referencedSources.count(s.first))
+ continue;
+
solAssert(s.second.scanner, "Scanner not available");
meta["sources"][s.first]["keccak256"] =
"0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes());
@@ -951,7 +935,7 @@ Json::Value CompilerStack::gasEstimates(string const& _contractName) const
for (auto const& it: contract.definedFunctions())
{
/// Exclude externally visible functions, constructor and the fallback function
- if (it->isPartOfExternalInterface() || it->isConstructor() || it->name().empty())
+ if (it->isPartOfExternalInterface() || it->isConstructor() || it->isFallback())
continue;
size_t entry = functionEntryPoint(_contractName, *it);
@@ -959,12 +943,14 @@ Json::Value CompilerStack::gasEstimates(string const& _contractName) const
if (entry > 0)
gas = GasEstimator::functionalEstimation(*items, entry, *it);
+ /// TODO: This could move into a method shared with externalSignature()
FunctionType type(*it);
string sig = it->name() + "(";
auto paramTypes = type.parameterTypes();
for (auto it = paramTypes.begin(); it != paramTypes.end(); ++it)
sig += (*it)->toString() + (it + 1 == paramTypes.end() ? "" : ",");
sig += ")";
+
internalFunctions[sig] = gasToJson(gas);
}
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 03a1b806..d287f224 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -93,87 +93,116 @@ public:
m_errorList(),
m_errorReporter(m_errorList) {}
- /// Sets path remappings in the format "context:prefix=target"
- void setRemappings(std::vector<std::string> const& _remappings);
+ /// @returns the list of errors that occured during parsing and type checking.
+ ErrorList const& errors() { return m_errorReporter.errors(); }
+
+ /// @returns the current state.
+ State state() const { return m_stackState; }
/// Resets the compiler to a state where the sources are not parsed or even removed.
+ /// Sets the state to SourcesSet if @a _keepSources is true, otherwise to Empty.
+ /// All settings, with the exception of remappings, are reset.
void reset(bool _keepSources = false);
- /// Adds a source object (e.g. file) to the parser. After this, parse has to be called again.
- /// @returns true if a source object by the name already existed and was replaced.
- void addSources(StringMap const& _nameContents, bool _isLibrary = false)
+ /// Sets path remappings in the format "context:prefix=target"
+ void setRemappings(std::vector<std::string> const& _remappings);
+
+ /// Sets library addresses. Addresses are cleared iff @a _libraries is missing.
+ /// Will not take effect before running compile.
+ void setLibraries(std::map<std::string, h160> const& _libraries = std::map<std::string, h160>{})
{
- for (auto const& i: _nameContents) addSource(i.first, i.second, _isLibrary);
+ m_libraries = _libraries;
}
+
+ /// Changes the optimiser settings.
+ /// Will not take effect before running compile.
+ void setOptimiserSettings(bool _optimize, unsigned _runs = 200)
+ {
+ m_optimize = _optimize;
+ m_optimizeRuns = _runs;
+ }
+
+ /// Adds a source object (e.g. file) to the parser. After this, parse has to be called again.
+ /// @returns true if a source object by the name already existed and was replaced.
bool addSource(std::string const& _name, std::string const& _content, bool _isLibrary = false);
- void setSource(std::string const& _sourceCode);
+
/// Parses all source units that were added
/// @returns false on error.
bool parse();
- /// Sets the given source code as the only source unit apart from standard sources and parses it.
- /// @returns false on error.
- bool parse(std::string const& _sourceCode);
- /// performs the analyisis steps (imports, scopesetting, syntaxCheck, referenceResolving,
+
+ /// Performs the analysis steps (imports, scopesetting, syntaxCheck, referenceResolving,
/// typechecking, staticAnalysis) on previously set sources
/// @returns false on error.
bool analyze();
+
/// Parses and analyzes all source units that were added
/// @returns false on error.
bool parseAndAnalyze();
- /// Sets the given source code as the only source unit apart from standard sources and parses and analyzes it.
- /// @returns false on error.
- bool parseAndAnalyze(std::string const& _sourceCode);
+
/// @returns a list of the contract names in the sources.
std::vector<std::string> contractNames() const;
/// Compiles the source units that were previously added and parsed.
/// @returns false on error.
- bool compile(
- bool _optimize = false,
- unsigned _runs = 200,
- std::map<std::string, h160> const& _libraries = std::map<std::string, h160>{}
- );
- /// Parses and compiles the given source code.
- /// @returns false on error.
- bool compile(std::string const& _sourceCode, bool _optimize = false, unsigned _runs = 200);
+ bool compile();
+
+ /// @returns the list of sources (paths) used
+ std::vector<std::string> sourceNames() const;
+
+ /// @returns a mapping assigning each source name its index inside the vector returned
+ /// by sourceNames().
+ std::map<std::string, unsigned> sourceIndices() const;
+
+ /// @returns the previously used scanner, useful for counting lines during error reporting.
+ Scanner const& scanner(std::string const& _sourceName = "") const;
+
+ /// @returns the parsed source unit with the supplied name.
+ SourceUnit const& ast(std::string const& _sourceName = "") const;
+
+ /// Helper function for logs printing. Do only use in error cases, it's quite expensive.
+ /// line and columns are numbered starting from 1 with following order:
+ /// start line, start column, end line, end column
+ std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
+
+ /// @returns either the contract's name or a mixture of its name and source file, sanitized for filesystem use
+ std::string const filesystemFriendlyName(std::string const& _contractName) const;
/// @returns the assembled object for a contract.
eth::LinkerObject const& object(std::string const& _contractName = "") const;
+
/// @returns the runtime object for the contract.
eth::LinkerObject const& runtimeObject(std::string const& _contractName = "") const;
+
/// @returns the bytecode of a contract that uses an already deployed contract via DELEGATECALL.
/// The returned bytes will contain a sequence of 20 bytes of the format "XXX...XXX" which have to
/// substituted by the actual address. Note that this sequence starts end ends in three X
/// characters but can contain anything in between.
eth::LinkerObject const& cloneObject(std::string const& _contractName = "") const;
+
/// @returns normal contract assembly items
eth::AssemblyItems const* assemblyItems(std::string const& _contractName = "") const;
+
/// @returns runtime contract assembly items
eth::AssemblyItems const* runtimeAssemblyItems(std::string const& _contractName = "") const;
+
/// @returns the string that provides a mapping between bytecode and sourcecode or a nullptr
/// if the contract does not (yet) have bytecode.
std::string const* sourceMapping(std::string const& _contractName = "") const;
+
/// @returns the string that provides a mapping between runtime bytecode and sourcecode.
/// if the contract does not (yet) have bytecode.
std::string const* runtimeSourceMapping(std::string const& _contractName = "") const;
- /// @returns either the contract's name or a mixture of its name and source file, sanitized for filesystem use
- std::string const filesystemFriendlyName(std::string const& _contractName) const;
-
/// Streams a verbose version of the assembly to @a _outStream.
/// @arg _sourceCodes is the map of input files to source code strings
/// @arg _inJsonFromat shows whether the out should be in Json format
/// Prerequisite: Successful compilation.
Json::Value streamAssembly(std::ostream& _outStream, std::string const& _contractName = "", StringMap _sourceCodes = StringMap(), bool _inJsonFormat = false) const;
- /// @returns the list of sources (paths) used
- std::vector<std::string> sourceNames() const;
- /// @returns a mapping assigning each source name its index inside the vector returned
- /// by sourceNames().
- std::map<std::string, unsigned> sourceIndices() const;
/// @returns a JSON representing the contract ABI.
/// Prerequisite: Successful call to parse or compile.
Json::Value const& contractABI(std::string const& _contractName = "") const;
+
/// @returns a JSON representing the contract's documentation.
/// Prerequisite: Successful call to parse or compile.
/// @param type The type of the documentation to get.
@@ -183,27 +212,13 @@ public:
/// @returns a JSON representing a map of method identifiers (hashes) to function names.
Json::Value methodIdentifiers(std::string const& _contractName) const;
- std::string const& onChainMetadata(std::string const& _contractName) const;
+ /// @returns the Contract Metadata
+ std::string const& metadata(std::string const& _contractName) const;
void useMetadataLiteralSources(bool _metadataLiteralSources) { m_metadataLiteralSources = _metadataLiteralSources; }
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
Json::Value gasEstimates(std::string const& _contractName) const;
- /// @returns the previously used scanner, useful for counting lines during error reporting.
- Scanner const& scanner(std::string const& _sourceName = "") const;
- /// @returns the parsed source unit with the supplied name.
- SourceUnit const& ast(std::string const& _sourceName = "") const;
-
- /// Helper function for logs printing. Do only use in error cases, it's quite expensive.
- /// line and columns are numbered starting from 1 with following order:
- /// start line, start column, end line, end column
- std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
-
- /// @returns the list of errors that occured during parsing and type checking.
- ErrorList const& errors() { return m_errorReporter.errors(); }
-
- State state() const { return m_stackState; }
-
private:
/**
* Information pertaining to one source unit, filled gradually during parsing and compilation.
@@ -223,13 +238,14 @@ private:
eth::LinkerObject object;
eth::LinkerObject runtimeObject;
eth::LinkerObject cloneObject;
- std::string onChainMetadata; ///< The metadata json that will be hashed into the chain.
+ std::string metadata; ///< The metadata json that will be hashed into the chain.
mutable std::unique_ptr<Json::Value const> abi;
mutable std::unique_ptr<Json::Value const> userDocumentation;
mutable std::unique_ptr<Json::Value const> devDocumentation;
mutable std::unique_ptr<std::string const> sourceMapping;
mutable std::unique_ptr<std::string const> runtimeSourceMapping;
};
+
/// Loads the missing sources from @a _ast (named @a _path) using the callback
/// @a m_readFile and stores the absolute paths of all imports in the AST annotations.
/// @returns the newly loaded sources.
@@ -255,7 +271,7 @@ private:
/// does not exist.
ContractDefinition const& contractDefinition(std::string const& _contractName) const;
- std::string createOnChainMetadata(Contract const& _contract) const;
+ std::string createMetadata(Contract const& _contract) const;
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
Json::Value const& contractABI(Contract const&) const;
Json::Value const& natspec(Contract const&, DocumentationType _type) const;
diff --git a/libsolidity/interface/ErrorReporter.cpp b/libsolidity/interface/ErrorReporter.cpp
index 6e2667a5..f9ef4ceb 100644
--- a/libsolidity/interface/ErrorReporter.cpp
+++ b/libsolidity/interface/ErrorReporter.cpp
@@ -42,11 +42,23 @@ void ErrorReporter::warning(string const& _description)
error(Error::Type::Warning, SourceLocation(), _description);
}
-void ErrorReporter::warning(SourceLocation const& _location, string const& _description)
+void ErrorReporter::warning(
+ SourceLocation const& _location,
+ string const& _description
+)
{
error(Error::Type::Warning, _location, _description);
}
+void ErrorReporter::warning(
+ SourceLocation const& _location,
+ string const& _description,
+ SecondarySourceLocation const& _secondaryLocation
+)
+{
+ error(Error::Type::Warning, _location, _secondaryLocation, _description);
+}
+
void ErrorReporter::error(Error::Type _type, SourceLocation const& _location, string const& _description)
{
auto err = make_shared<Error>(_type);
diff --git a/libsolidity/interface/ErrorReporter.h b/libsolidity/interface/ErrorReporter.h
index e5605d24..8b066a3e 100644
--- a/libsolidity/interface/ErrorReporter.h
+++ b/libsolidity/interface/ErrorReporter.h
@@ -41,30 +41,30 @@ public:
ErrorReporter& operator=(ErrorReporter const& _errorReporter);
- void warning(std::string const& _description = std::string());
+ void warning(std::string const& _description);
+
+ void warning(SourceLocation const& _location, std::string const& _description);
void warning(
- SourceLocation const& _location = SourceLocation(),
- std::string const& _description = std::string()
+ SourceLocation const& _location,
+ std::string const& _description,
+ SecondarySourceLocation const& _secondaryLocation
);
void error(
Error::Type _type,
- SourceLocation const& _location = SourceLocation(),
- std::string const& _description = std::string()
- );
-
- void declarationError(
SourceLocation const& _location,
- SecondarySourceLocation const& _secondaryLocation = SecondarySourceLocation(),
- std::string const& _description = std::string()
+ std::string const& _description
);
void declarationError(
SourceLocation const& _location,
- std::string const& _description = std::string()
+ SecondarySourceLocation const& _secondaryLocation,
+ std::string const& _description
);
+ void declarationError(SourceLocation const& _location, std::string const& _description);
+
void fatalDeclarationError(SourceLocation const& _location, std::string const& _description);
void parserError(SourceLocation const& _location, std::string const& _description);
diff --git a/libsolidity/interface/Exceptions.cpp b/libsolidity/interface/Exceptions.cpp
index 9f2a2d06..a837dce6 100644
--- a/libsolidity/interface/Exceptions.cpp
+++ b/libsolidity/interface/Exceptions.cpp
@@ -67,16 +67,3 @@ Error::Error(Error::Type _type, const std::string& _description, const SourceLoc
*this << errinfo_sourceLocation(_location);
*this << errinfo_comment(_description);
}
-
-string Exception::lineInfo() const
-{
- char const* const* file = boost::get_error_info<boost::throw_file>(*this);
- int const* line = boost::get_error_info<boost::throw_line>(*this);
- string ret;
- if (file)
- ret += *file;
- ret += ':';
- if (line)
- ret += boost::lexical_cast<string>(*line);
- return ret;
-}
diff --git a/libsolidity/interface/Natspec.cpp b/libsolidity/interface/Natspec.cpp
index 70486e23..7f7084ef 100644
--- a/libsolidity/interface/Natspec.cpp
+++ b/libsolidity/interface/Natspec.cpp
@@ -26,28 +26,11 @@
#include <libsolidity/interface/Natspec.h>
#include <boost/range/irange.hpp>
#include <libsolidity/ast/AST.h>
-#include <libsolidity/interface/CompilerStack.h>
using namespace std;
using namespace dev;
using namespace dev::solidity;
-Json::Value Natspec::documentation(
- ContractDefinition const& _contractDef,
- DocumentationType _type
-)
-{
- switch(_type)
- {
- case DocumentationType::NatspecUser:
- return userDocumentation(_contractDef);
- case DocumentationType::NatspecDev:
- return devDocumentation(_contractDef);
- }
-
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
-}
-
Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
{
Json::Value doc;
diff --git a/libsolidity/interface/Natspec.h b/libsolidity/interface/Natspec.h
index bec9acd2..9ac3efea 100644
--- a/libsolidity/interface/Natspec.h
+++ b/libsolidity/interface/Natspec.h
@@ -39,7 +39,6 @@ class ContractDefinition;
class Type;
using TypePointer = std::shared_ptr<Type const>;
struct DocTag;
-enum class DocumentationType: uint8_t;
enum class DocTagType: uint8_t
{
@@ -61,15 +60,6 @@ enum class CommentOwner
class Natspec
{
public:
- /// Get the given type of documentation
- /// @param _contractDef The contract definition
- /// @param _type The type of the documentation. Can be one of the
- /// types provided by @c DocumentationType
- /// @return A JSON representation of provided type
- static Json::Value documentation(
- ContractDefinition const& _contractDef,
- DocumentationType _type
- );
/// Get the User documentation of the contract
/// @param _contractDef The contract definition
/// @return A JSON representation of the contract's user documentation
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index 15bb7592..dd135ce5 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -247,8 +247,9 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
m_compilerStack.setRemappings(remappings);
Json::Value optimizerSettings = settings.get("optimizer", Json::Value());
- bool optimize = optimizerSettings.get("enabled", Json::Value(false)).asBool();
- unsigned optimizeRuns = optimizerSettings.get("runs", Json::Value(200u)).asUInt();
+ bool const optimize = optimizerSettings.get("enabled", Json::Value(false)).asBool();
+ unsigned const optimizeRuns = optimizerSettings.get("runs", Json::Value(200u)).asUInt();
+ m_compilerStack.setOptimiserSettings(optimize, optimizeRuns);
map<string, h160> libraries;
Json::Value jsonLibraries = settings.get("libraries", Json::Value());
@@ -259,6 +260,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
// @TODO use libraries only for the given source
libraries[library] = h160(jsonSourceName[library].asString());
}
+ m_compilerStack.setLibraries(libraries);
Json::Value metadataSettings = settings.get("metadata", Json::Value());
m_compilerStack.useMetadataLiteralSources(metadataSettings.get("useLiteralContent", Json::Value(false)).asBool());
@@ -267,7 +269,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
try
{
- m_compilerStack.compile(optimize, optimizeRuns, libraries);
+ m_compilerStack.compile();
for (auto const& error: m_compilerStack.errors())
{
@@ -283,24 +285,27 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
));
}
}
+ /// This is only thrown in a very few locations.
catch (Error const& _error)
{
- if (_error.type() == Error::Type::DocstringParsingError)
- errors.append(formatError(
- false,
- "DocstringParsingError",
- "general",
- "Documentation parsing error: " + *boost::get_error_info<errinfo_comment>(_error)
- ));
- else
- errors.append(formatErrorWithException(
- _error,
- false,
- _error.typeName(),
- "general",
- "",
- scannerFromSourceName
- ));
+ errors.append(formatErrorWithException(
+ _error,
+ false,
+ _error.typeName(),
+ "general",
+ "Uncaught error: ",
+ scannerFromSourceName
+ ));
+ }
+ /// This should not be leaked from compile().
+ catch (FatalError const& _exception)
+ {
+ errors.append(formatError(
+ false,
+ "FatalError",
+ "general",
+ "Uncaught fatal error: " + boost::diagnostic_information(_exception)
+ ));
}
catch (CompilerError const& _exception)
{
@@ -320,7 +325,8 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
false,
"InternalCompilerError",
"general",
- "Internal compiler error (" + _exception.lineInfo() + ")", scannerFromSourceName
+ "Internal compiler error (" + _exception.lineInfo() + ")",
+ scannerFromSourceName
));
}
catch (UnimplementedFeatureError const& _exception)
@@ -331,7 +337,8 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
"UnimplementedFeatureError",
"general",
"Unimplemented feature (" + _exception.lineInfo() + ")",
- scannerFromSourceName));
+ scannerFromSourceName
+ ));
}
catch (Exception const& _exception)
{
@@ -352,27 +359,27 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
));
}
- Json::Value output = Json::objectValue;
-
- if (errors.size() > 0)
- output["errors"] = errors;
-
- bool analysisSuccess = m_compilerStack.state() >= CompilerStack::State::AnalysisSuccessful;
- bool compilationSuccess = m_compilerStack.state() == CompilerStack::State::CompilationSuccessful;
+ bool const analysisSuccess = m_compilerStack.state() >= CompilerStack::State::AnalysisSuccessful;
+ bool const compilationSuccess = m_compilerStack.state() == CompilerStack::State::CompilationSuccessful;
/// Inconsistent state - stop here to receive error reports from users
if (!compilationSuccess && (errors.size() == 0))
return formatFatalError("InternalCompilerError", "No error reported, but compilation failed.");
+ Json::Value output = Json::objectValue;
+
+ if (errors.size() > 0)
+ output["errors"] = errors;
+
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
- for (auto const& source: analysisSuccess ? m_compilerStack.sourceNames() : vector<string>())
+ for (string const& sourceName: analysisSuccess ? m_compilerStack.sourceNames() : vector<string>())
{
Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++;
- sourceResult["ast"] = ASTJsonConverter(false, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(source));
- sourceResult["legacyAST"] = ASTJsonConverter(true, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(source));
- output["sources"][source] = sourceResult;
+ sourceResult["ast"] = ASTJsonConverter(false, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
+ sourceResult["legacyAST"] = ASTJsonConverter(true, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
+ output["sources"][sourceName] = sourceResult;
}
Json::Value contractsOutput = Json::objectValue;
@@ -386,7 +393,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
// ABI, documentation and metadata
Json::Value contractData(Json::objectValue);
contractData["abi"] = m_compilerStack.contractABI(contractName);
- contractData["metadata"] = m_compilerStack.onChainMetadata(contractName);
+ contractData["metadata"] = m_compilerStack.metadata(contractName);
contractData["userdoc"] = m_compilerStack.natspec(contractName, DocumentationType::NatspecUser);
contractData["devdoc"] = m_compilerStack.natspec(contractName, DocumentationType::NatspecDev);