Improved external interface for multi-source and multi-contract compilation.

This commit is contained in:
Christian 2014-12-03 18:52:28 +01:00
parent 254df50fea
commit d2cf345483
10 changed files with 50 additions and 43 deletions

View File

@ -37,14 +37,13 @@ namespace solidity
*/
struct Location
{
Location(int _start, int _end): start(_start), end(_end) { }
Location(int _start, int _end, std::shared_ptr<std::string const> _sourceName):
start(_start), end(_end), sourceName(_sourceName) { }
Location(): start(-1), end(-1) { }
bool IsValid() const { return !!sourceName && start >= 0 && end >= start; }
std::shared_ptr<std::string> sourceName;
int start;
int end;
std::shared_ptr<std::string const> sourceName;
};
/// Stream output for Location (used e.g. in boost exceptions).

View File

@ -81,10 +81,20 @@ void CompilerStack::parse(string const& _sourceCode)
parse();
}
void CompilerStack::compile(bool _optimize)
vector<string> CompilerStack::getContractNames()
{
if (!m_parseSuccessful)
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;
}
void CompilerStack::compile(bool _optimize)
{
if (!m_parseSuccessful)
parse();
for (Source const* source: m_sourceOrder)
for (ASTPointer<ASTNode> const& node: source->ast->getNodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))

View File

@ -54,6 +54,9 @@ public:
void parse();
/// Sets the given source code as the only source unit and parses it.
void parse(std::string const& _sourceCode);
/// Returns a list of the contract names in the sources.
std::vector<std::string> getContractNames();
/// Compiles the source units that were prevously added and parsed.
void compile(bool _optimize = false);
/// Parses and compiles the given source code.

View File

@ -37,7 +37,6 @@ struct DeclarationError: virtual Exception {};
struct CompilerError: virtual Exception {};
struct InternalCompilerError: virtual Exception {};
typedef boost::error_info<struct tag_sourcePosition, int> errinfo_sourcePosition;
typedef boost::error_info<struct tag_sourceLocation, Location> errinfo_sourceLocation;
}

View File

@ -39,7 +39,8 @@ namespace solidity
class Parser::ASTNodeFactory
{
public:
ASTNodeFactory(Parser const& _parser): m_parser(_parser), m_location(_parser.getPosition(), -1) {}
ASTNodeFactory(Parser const& _parser):
m_parser(_parser), m_location(_parser.getPosition(), -1, _parser.getSourceName()) {}
void markEndPosition() { m_location.end = m_parser.getEndPosition(); }
void setLocationEmpty() { m_location.end = m_location.start; }
@ -81,6 +82,11 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
return nodeFactory.createNode<SourceUnit>(nodes);
}
std::shared_ptr<const string> const& Parser::getSourceName() const
{
return m_scanner->getSourceName();
}
int Parser::getPosition() const
{
return m_scanner->getCurrentLocation().start;
@ -579,7 +585,8 @@ ASTPointer<ASTString> Parser::getLiteralAndAdvance()
ParserError Parser::createParserError(string const& _description) const
{
return ParserError() << errinfo_sourcePosition(getPosition()) << errinfo_comment(_description);
return ParserError() << errinfo_sourceLocation(Location(getPosition(), getPosition(), getSourceName()))
<< errinfo_comment(_description);
}

View File

@ -35,6 +35,7 @@ class Parser
{
public:
ASTPointer<SourceUnit> parse(std::shared_ptr<Scanner> const& _scanner);
std::shared_ptr<std::string const> const& getSourceName() const;
private:
class ASTNodeFactory;

View File

@ -143,16 +143,10 @@ private:
}; // end of LiteralScope class
void Scanner::reset(CharStream const& _source, std::string const& _sourceName)
void Scanner::reset(CharStream const& _source, string const& _sourceName)
{
m_source = _source;
shared_ptr<string> sourceName = make_shared<string>(_sourceName);
m_currentToken.location.sourceName = sourceName;
m_nextToken.location.sourceName = sourceName;
m_skippedComment.location.sourceName = sourceName;
m_nextSkippedComment.location.sourceName = sourceName;
m_sourceName = make_shared<string const>(_sourceName);
reset();
}

View File

@ -142,6 +142,8 @@ public:
std::string const& peekLiteral() const { return m_nextToken.literal; }
///@}
std::shared_ptr<std::string const> const& getSourceName() const { return m_sourceName; }
///@{
///@name Error printing helper functions
/// Functions that help pretty-printing parse errors
@ -206,6 +208,7 @@ private:
TokenDesc m_nextToken; // desc for next token (one token look-ahead)
CharStream m_source;
std::shared_ptr<std::string const> m_sourceName;
/// one character look-ahead, equals 0 at end of input
char m_char;

View File

@ -21,6 +21,7 @@
*/
#include <libsolidity/SourceReferenceFormatter.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Exceptions.h>
@ -38,7 +39,6 @@ void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
int startLine;
int startColumn;
tie(startLine, startColumn) = _scanner.translatePositionToLineColumn(_location.start);
_stream << "starting at line " << (startLine + 1) << ", column " << (startColumn + 1) << "\n";
int endLine;
int endColumn;
tie(endLine, endColumn) = _scanner.translatePositionToLineColumn(_location.end);
@ -58,37 +58,28 @@ void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
<< "Spanning multiple lines.\n";
}
void SourceReferenceFormatter::printSourcePosition(ostream& _stream,
int _position,
const Scanner& _scanner)
{
int line;
int column;
tie(line, column) = _scanner.translatePositionToLineColumn(_position);
_stream << "at line " << (line + 1) << ", column " << (column + 1) << endl
<< _scanner.getLineAtPosition(_position) << endl
<< string(column, ' ') << "^" << endl;
}
void SourceReferenceFormatter::printExceptionInformation(ostream& _stream,
Exception const& _exception,
string const& _name,
Scanner const& _scanner)
CompilerStack& _compiler)
{
Location const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
Scanner const* scanner;
if (location)
{
scanner = &_compiler.getScanner(*location->sourceName);
int startLine;
int startColumn;
tie(startLine, startColumn) = scanner->translatePositionToLineColumn(location->start);
_stream << *location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": ";
}
_stream << _name;
if (string const* description = boost::get_error_info<errinfo_comment>(_exception))
_stream << ": " << *description;
_stream << ": " << *description << endl;
if (int const* position = boost::get_error_info<errinfo_sourcePosition>(_exception))
{
_stream << " ";
printSourcePosition(_stream, *position, _scanner);
}
if (Location const* location = boost::get_error_info<errinfo_sourceLocation>(_exception))
{
_stream << " ";
printSourceLocation(_stream, *location, _scanner);
}
if (location)
printSourceLocation(_stream, *location, *scanner);
}
}

View File

@ -34,14 +34,14 @@ namespace solidity
{
class Scanner; // forward
class CompilerStack; // forward
struct SourceReferenceFormatter
{
public:
static void printSourceLocation(std::ostream& _stream, Location const& _location, Scanner const& _scanner);
static void printSourcePosition(std::ostream& _stream, int _position, Scanner const& _scanner);
static void printExceptionInformation(std::ostream& _stream, Exception const& _exception,
std::string const& _name, Scanner const& _scanner);
std::string const& _name, CompilerStack& _compiler);
};
}