added Error class for all kind of errors

Conflicts:
	libsolidity/Exceptions.h
This commit is contained in:
LianaHus
2015-10-14 20:27:41 +02:00
parent 95ad872678
commit 742e5b259a
16 changed files with 107 additions and 76 deletions
+2 -2
View File
@@ -51,9 +51,9 @@ ASTAnnotation& ASTNode::annotation() const
return *m_annotation;
}
TypeError ASTNode::createTypeError(string const& _description) const
Error ASTNode::createTypeError(string const& _description) const
{
return TypeError() << errinfo_sourceLocation(location()) << errinfo_comment(_description);
return Error(Error::Type::TypeError) << errinfo_sourceLocation(location()) << errinfo_comment(_description);
}
map<FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions() const
+9 -5
View File
@@ -75,7 +75,7 @@ public:
/// Creates a @ref TypeError exception and decorates it with the location of the node and
/// the given description
TypeError createTypeError(std::string const& _description) const;
Error createTypeError(std::string const& _description) const;
///@todo make this const-safe by providing a different way to access the annotation
virtual ASTAnnotation& annotation() const;
@@ -660,10 +660,14 @@ class MagicVariableDeclaration: public Declaration
public:
MagicVariableDeclaration(ASTString const& _name, std::shared_ptr<Type const> const& _type):
Declaration(SourceLocation(), std::make_shared<ASTString>(_name)), m_type(_type) {}
virtual void accept(ASTVisitor&) override { BOOST_THROW_EXCEPTION(InternalCompilerError()
<< errinfo_comment("MagicVariableDeclaration used inside real AST.")); }
virtual void accept(ASTConstVisitor&) const override { BOOST_THROW_EXCEPTION(InternalCompilerError()
<< errinfo_comment("MagicVariableDeclaration used inside real AST.")); }
virtual void accept(ASTVisitor&) override
{
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST."));
}
virtual void accept(ASTConstVisitor&) const override
{
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("MagicVariableDeclaration used inside real AST."));
}
virtual TypePointer type(ContractDefinition const*) const override { return m_type; }
+2 -2
View File
@@ -107,7 +107,7 @@ bool CompilerStack::parse()
resolveImports();
m_globalContext = make_shared<GlobalContext>();
NameAndTypeResolver resolver(m_globalContext->declarations());
NameAndTypeResolver resolver(m_globalContext->declarations(), m_errors);
for (Source const* source: m_sourceOrder)
resolver.registerDeclarations(*source->ast);
for (Source const* source: m_sourceOrder)
@@ -345,7 +345,7 @@ void CompilerStack::resolveImports()
string const& id = import->identifier();
if (!m_sources.count(id))
BOOST_THROW_EXCEPTION(
ParserError()
Error(Error::Type::ParserError)
<< errinfo_sourceLocation(import->location())
<< errinfo_comment("Source not found.")
);
+3 -2
View File
@@ -33,6 +33,7 @@
#include <libdevcore/FixedHash.h>
#include <libevmasm/SourceLocation.h>
#include <libevmasm/LinkerObject.h>
#include <libsolidity/Exceptions.h>
namespace dev
{
@@ -164,7 +165,7 @@ public:
std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
/// @returns the list of errors that occured during parsing and type checking.
std::vector<std::shared_ptr<Error const>> const& errors() const { return m_errors; }
ErrorList const& errors() const { return m_errors; }
private:
/**
@@ -212,7 +213,7 @@ private:
std::shared_ptr<GlobalContext> m_globalContext;
std::vector<Source const*> m_sourceOrder;
std::map<std::string const, Contract> m_contracts;
std::vector<std::shared_ptr<Error const>> m_errors;
ErrorList m_errors;
};
}
+46 -6
View File
@@ -31,13 +31,51 @@ namespace dev
{
namespace solidity
{
struct Error: virtual Exception {};
struct ParserError: virtual Error {};
struct TypeError: virtual Error {};
struct DeclarationError: virtual Error {};
struct DocstringParsingError: virtual Error {};
struct Warning: virtual Error {};
class Error: virtual public Exception
{
public:
enum class Type
{
DeclarationError,
DocstringParsingError,
ParserError,
TypeError,
Warning
};
Error(Type _type) : m_type(_type)
{
switch(m_type)
{
case Type::DeclarationError:
m_typeName = "Declaration Error";
break;
case Type::DocstringParsingError:
m_typeName = "Docstring Parsing Error";
break;
case Type::ParserError:
m_typeName = "Parser Error";
break;
case Type::TypeError:
m_typeName = "Type Error";
break;
case Type::Warning:
m_typeName = "Warning";
break;
default:
m_typeName = "Error";
break;
}
}
Type type() { return m_type; }
std::string const& typeName() const { return m_typeName; }
private:
Type m_type;
std::string m_typeName;
};
struct CompilerError: virtual Exception {};
struct InternalCompilerError: virtual Exception {};
@@ -56,6 +94,8 @@ public:
std::vector<errorSourceLocationInfo> infos;
};
using ErrorList = std::vector<std::shared_ptr<Error const>>;
using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
+8 -8
View File
@@ -243,7 +243,7 @@ string InterfaceHandler::devDocumentation(ContractDefinition const& _contractDef
if (find(paramNames.begin(), paramNames.end(), pair.first) == paramNames.end())
// LTODO: mismatching parameter name, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(
DocstringParsingError() <<
Error(Error::Type::DocstringParsingError) <<
errinfo_comment("documented parameter \"" + pair.first + "\" not found in the parameter list of the function.")
);
params[pair.first] = pair.second;
@@ -310,7 +310,7 @@ string::const_iterator InterfaceHandler::parseDocTagParam(
// find param name
auto currPos = find(_pos, _end, ' ');
if (currPos == _end)
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("End of param name not found" + string(_pos, _end)));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("End of param name not found" + string(_pos, _end)));
auto paramName = string(_pos, currPos);
@@ -369,7 +369,7 @@ string::const_iterator InterfaceHandler::parseDocTag(
return parseDocTagLine(_pos, _end, m_author, DocTagType::Author, false);
else
// LTODO: for now this else makes no sense but later comments will go to more language constructs
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag is legal only for contracts"));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("@author tag is legal only for contracts"));
}
else if (_tag == "title")
{
@@ -377,13 +377,13 @@ string::const_iterator InterfaceHandler::parseDocTag(
return parseDocTagLine(_pos, _end, m_title, DocTagType::Title, false);
else
// LTODO: Unknown tag, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag is legal only for contracts"));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("@title tag is legal only for contracts"));
}
else if (_tag == "param")
return parseDocTagParam(_pos, _end);
else
// LTODO: Unknown tag, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("Unknown tag " + _tag + " encountered"));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("Unknown tag " + _tag + " encountered"));
}
else
return appendDocTag(_pos, _end, _owner);
@@ -410,13 +410,13 @@ string::const_iterator InterfaceHandler::appendDocTag(
return parseDocTagLine(_pos, _end, m_author, DocTagType::Author, true);
else
// LTODO: Unknown tag, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag in illegal comment"));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("@author tag in illegal comment"));
case DocTagType::Title:
if (_owner == CommentOwner::Contract)
return parseDocTagLine(_pos, _end, m_title, DocTagType::Title, true);
else
// LTODO: Unknown tag, throw some form of warning and not just an exception
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag in illegal comment"));
BOOST_THROW_EXCEPTION(Error(Error::Type::DocstringParsingError) << errinfo_comment("@title tag in illegal comment"));
case DocTagType::Param:
return appendDocTagParam(_pos, _end);
default:
@@ -451,7 +451,7 @@ void InterfaceHandler::parseDocString(string const& _string, CommentOwner _owner
auto tagNameEndPos = firstSpaceOrNl(tagPos, end);
if (tagNameEndPos == end)
BOOST_THROW_EXCEPTION(
DocstringParsingError() <<
Error(Error::Type::DocstringParsingError) <<
errinfo_comment("End of tag " + string(tagPos, tagNameEndPos) + "not found"));
currPos = parseDocTag(tagNameEndPos + 1, end, string(tagPos + 1, tagNameEndPos), _owner);
+6 -4
View File
@@ -33,8 +33,10 @@ namespace solidity
{
NameAndTypeResolver::NameAndTypeResolver(
vector<Declaration const*> const& _globals
)
vector<Declaration const*> const& _globals,
ErrorList& _errors
) :
m_errors(_errors)
{
for (Declaration const* declaration: _globals)
m_scopes[nullptr].registerDeclaration(*declaration);
@@ -163,7 +165,7 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes())
if (!parameter)
BOOST_THROW_EXCEPTION(
DeclarationError() <<
Error(Error::Type::DeclarationError) <<
errinfo_sourceLocation(_identifier.location()) <<
errinfo_comment("Function type can not be used in this context")
);
@@ -408,7 +410,7 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
}
BOOST_THROW_EXCEPTION(
DeclarationError() <<
Error(Error::Type::DeclarationError) <<
errinfo_sourceLocation(secondDeclarationLocation) <<
errinfo_comment("Identifier already declared.") <<
errinfo_secondarySourceLocation(
+2 -1
View File
@@ -42,7 +42,7 @@ namespace solidity
class NameAndTypeResolver: private boost::noncopyable
{
public:
NameAndTypeResolver(std::vector<Declaration const*> const& _globals);
NameAndTypeResolver(std::vector<Declaration const*> const& _globals, ErrorList& _errors);
/// Registers all declarations found in the source unit.
void registerDeclarations(SourceUnit& _sourceUnit);
/// Resolves all names and types referenced from the given contract.
@@ -91,6 +91,7 @@ private:
std::map<ASTNode const*, DeclarationContainer> m_scopes;
DeclarationContainer* m_currentScope = nullptr;
ErrorList& m_errors;
};
/**
+2 -2
View File
@@ -1156,9 +1156,9 @@ ASTPointer<ParameterList> Parser::createEmptyParameterList()
return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
}
ParserError Parser::createParserError(string const& _description) const
Error Parser::createParserError(string const& _description) const
{
return ParserError() <<
return Error(Error::Type::ParserError) <<
errinfo_sourceLocation(SourceLocation(position(), position(), sourceName())) <<
errinfo_comment(_description);
}
+1 -1
View File
@@ -147,7 +147,7 @@ private:
/// Creates a @ref ParserError exception and annotates it with the current position and the
/// given @a _description.
ParserError createParserError(std::string const& _description) const;
Error createParserError(std::string const& _description) const;
std::shared_ptr<Scanner> m_scanner;
/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.
+5 -4
View File
@@ -67,6 +67,7 @@ TypePointer const& TypeChecker::type(VariableDeclaration const& _variable) const
bool TypeChecker::visit(ContractDefinition const& _contract)
{
// We force our own visiting order here.
ASTNode::listAccept(_contract.definedStructs(), *this);
ASTNode::listAccept(_contract.baseContracts(), *this);
@@ -87,7 +88,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
{
if (fallbackFunction)
{
auto err = make_shared<DeclarationError>();
auto err = make_shared<Error>(Error::Type::DeclarationError);
*err << errinfo_comment("Only one fallback function is allowed.");
m_errors.push_back(err);
}
@@ -143,7 +144,7 @@ void TypeChecker::checkContractDuplicateFunctions(ContractDefinition const& _con
for (; it != functions[_contract.name()].end(); ++it)
ssl.append("Another declaration is here:", (*it)->location());
auto err = make_shared<DeclarationError>();
auto err = make_shared<Error>(Error(Error::Type::DeclarationError));
*err <<
errinfo_sourceLocation(functions[_contract.name()].front()->location()) <<
errinfo_comment("More than one constructor defined.") <<
@@ -157,7 +158,7 @@ void TypeChecker::checkContractDuplicateFunctions(ContractDefinition const& _con
for (size_t j = i + 1; j < overloads.size(); ++j)
if (FunctionType(*overloads[i]).hasEqualArgumentTypes(FunctionType(*overloads[j])))
{
auto err = make_shared<DeclarationError>();
auto err = make_shared<Error>(Error(Error::Type::DeclarationError));
*err <<
errinfo_sourceLocation(overloads[j]->location()) <<
errinfo_comment("Function with same name and arguments defined twice.") <<
@@ -1251,7 +1252,7 @@ void TypeChecker::requireLValue(Expression const& _expression)
void TypeChecker::typeError(ASTNode const& _node, string const& _description)
{
auto err = make_shared<TypeError>();
auto err = make_shared<Error>(Error(Error::Type::TypeError));;
*err <<
errinfo_sourceLocation(_node.location()) <<
errinfo_comment(_description);
+3 -3
View File
@@ -50,7 +50,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types)
byteOffset = 0;
}
if (slotOffset >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Object too large for storage."));
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Object too large for storage."));
offsets[i] = make_pair(u256(slotOffset), byteOffset);
solAssert(type->storageSize() >= 1, "Invalid storage size.");
if (type->storageSize() == 1 && byteOffset + type->storageBytes() <= 32)
@@ -64,7 +64,7 @@ void StorageOffsets::computeOffsets(TypePointers const& _types)
if (byteOffset > 0)
++slotOffset;
if (slotOffset >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Object too large for storage."));
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Object too large for storage."));
m_storageSize = u256(slotOffset);
swap(m_offsets, offsets);
}
@@ -805,7 +805,7 @@ u256 ArrayType::storageSize() const
else
size = bigint(length()) * baseType()->storageSize();
if (size >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Array too large for storage."));
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Array too large for storage."));
return max<u256>(1, u256(size));
}