mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
errors instead of exceptions
Conflicts: libsolidity/CompilerStack.cpp libsolidity/NameAndTypeResolver.cpp libsolidity/NameAndTypeResolver.h libsolidity/TypeChecker.cpp test/libsolidity/SolidityNameAndTypeResolution.cpp
This commit is contained in:
parent
8f7f22c5a6
commit
c3491e4469
@ -137,7 +137,7 @@ ModifierDefinition const& CompilerContext::functionModifier(string const& _name)
|
|||||||
if (modifier->name() == _name)
|
if (modifier->name() == _name)
|
||||||
return *modifier.get();
|
return *modifier.get();
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError()
|
BOOST_THROW_EXCEPTION(InternalCompilerError()
|
||||||
<< errinfo_comment("Function modifier " + _name + " not found."));
|
<< errinfo_comment("Function modifier " + _name + " not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned CompilerContext::baseStackOffsetOfVariable(Declaration const& _declaration) const
|
unsigned CompilerContext::baseStackOffsetOfVariable(Declaration const& _declaration) const
|
||||||
|
@ -97,30 +97,41 @@ void CompilerStack::setSource(string const& _sourceCode)
|
|||||||
|
|
||||||
bool CompilerStack::parse()
|
bool CompilerStack::parse()
|
||||||
{
|
{
|
||||||
|
// todo not sure about clear. can contain warnings
|
||||||
m_errors.clear();
|
m_errors.clear();
|
||||||
|
|
||||||
for (auto& sourcePair: m_sources)
|
for (auto& sourcePair: m_sources)
|
||||||
{
|
{
|
||||||
sourcePair.second.scanner->reset();
|
sourcePair.second.scanner->reset();
|
||||||
sourcePair.second.ast = Parser().parse(sourcePair.second.scanner);
|
sourcePair.second.ast = Parser(m_errors).parse(sourcePair.second.scanner); // todo check for errors
|
||||||
}
|
}
|
||||||
|
if (!Error::containsOnlyWarnings(m_errors))
|
||||||
|
// errors while parsing. sould stop before type checking
|
||||||
|
return false;
|
||||||
|
|
||||||
resolveImports();
|
resolveImports();
|
||||||
|
|
||||||
m_globalContext = make_shared<GlobalContext>();
|
m_globalContext = make_shared<GlobalContext>();
|
||||||
|
bool success = true;
|
||||||
NameAndTypeResolver resolver(m_globalContext->declarations(), m_errors);
|
NameAndTypeResolver resolver(m_globalContext->declarations(), m_errors);
|
||||||
for (Source const* source: m_sourceOrder)
|
for (Source const* source: m_sourceOrder)
|
||||||
resolver.registerDeclarations(*source->ast);
|
success = success && resolver.registerDeclarations(*source->ast);
|
||||||
for (Source const* source: m_sourceOrder)
|
for (Source const* source: m_sourceOrder)
|
||||||
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
|
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
m_globalContext->setCurrentContract(*contract);
|
m_globalContext->setCurrentContract(*contract);
|
||||||
resolver.updateDeclaration(*m_globalContext->currentThis());
|
success = success && resolver.updateDeclaration(*m_globalContext->currentThis());
|
||||||
resolver.updateDeclaration(*m_globalContext->currentSuper());
|
success = success && resolver.updateDeclaration(*m_globalContext->currentSuper());
|
||||||
resolver.resolveNamesAndTypes(*contract);
|
success = success && resolver.resolveNamesAndTypes(*contract);
|
||||||
m_contracts[contract->name()].contract = contract;
|
m_contracts[contract->name()].contract = contract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
m_parseSuccessful = false;
|
||||||
|
return m_parseSuccessful;
|
||||||
|
}
|
||||||
InterfaceHandler interfaceHandler;
|
InterfaceHandler interfaceHandler;
|
||||||
bool typesFine = true;
|
bool typesFine = true;
|
||||||
for (Source const* source: m_sourceOrder)
|
for (Source const* source: m_sourceOrder)
|
||||||
@ -137,6 +148,7 @@ bool CompilerStack::parse()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
typesFine = false;
|
typesFine = false;
|
||||||
|
|
||||||
m_contracts[contract->name()].contract = contract;
|
m_contracts[contract->name()].contract = contract;
|
||||||
m_errors += typeChecker.errors();
|
m_errors += typeChecker.errors();
|
||||||
}
|
}
|
||||||
@ -253,9 +265,8 @@ string const& CompilerStack::metadata(string const& _contractName, Documentation
|
|||||||
if (!m_parseSuccessful)
|
if (!m_parseSuccessful)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
||||||
|
|
||||||
Contract const& currentContract = contract(_contractName);
|
|
||||||
|
|
||||||
std::unique_ptr<string const>* doc;
|
std::unique_ptr<string const>* doc;
|
||||||
|
Contract const& currentContract = contract(_contractName);
|
||||||
|
|
||||||
// checks wheather we already have the documentation
|
// checks wheather we already have the documentation
|
||||||
switch (_type)
|
switch (_type)
|
||||||
@ -346,9 +357,10 @@ void CompilerStack::resolveImports()
|
|||||||
if (!m_sources.count(id))
|
if (!m_sources.count(id))
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
Error(Error::Type::ParserError)
|
Error(Error::Type::ParserError)
|
||||||
<< errinfo_sourceLocation(import->location())
|
<< errinfo_sourceLocation(import->location())
|
||||||
<< errinfo_comment("Source not found.")
|
<< errinfo_comment("Source not found.")
|
||||||
);
|
);
|
||||||
|
|
||||||
toposort(&m_sources[id]);
|
toposort(&m_sources[id]);
|
||||||
}
|
}
|
||||||
sourceOrder.push_back(_source);
|
sourceOrder.push_back(_source);
|
||||||
@ -414,10 +426,12 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co
|
|||||||
auto it = m_sources.find(_sourceName);
|
auto it = m_sources.find(_sourceName);
|
||||||
if (it == m_sources.end())
|
if (it == m_sources.end())
|
||||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Given source file not found."));
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Given source file not found."));
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerStack::Contract::Contract(): interfaceHandler(make_shared<InterfaceHandler>()) {}
|
CompilerStack::Contract::Contract(): interfaceHandler(make_shared<InterfaceHandler>()) {}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,6 +167,7 @@ public:
|
|||||||
/// @returns the list of errors that occured during parsing and type checking.
|
/// @returns the list of errors that occured during parsing and type checking.
|
||||||
ErrorList const& errors() const { return m_errors; }
|
ErrorList const& errors() const { return m_errors; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Information pertaining to one source unit, filled gradually during parsing and compilation.
|
* Information pertaining to one source unit, filled gradually during parsing and compilation.
|
||||||
|
@ -26,11 +26,18 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <libdevcore/Exceptions.h>
|
#include <libdevcore/Exceptions.h>
|
||||||
#include <libevmasm/SourceLocation.h>
|
#include <libevmasm/SourceLocation.h>
|
||||||
|
#include <libsolidity/Utils.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
class Error;
|
||||||
|
using ErrorList = std::vector<std::shared_ptr<Error const>>;
|
||||||
|
|
||||||
|
struct CompilerError: virtual Exception {};
|
||||||
|
struct InternalCompilerError: virtual Exception {};
|
||||||
|
struct fatalError: virtual Exception {}; //todo rename to FatalError
|
||||||
|
|
||||||
class Error: virtual public Exception
|
class Error: virtual public Exception
|
||||||
{
|
{
|
||||||
@ -41,7 +48,6 @@ public:
|
|||||||
DocstringParsingError,
|
DocstringParsingError,
|
||||||
ParserError,
|
ParserError,
|
||||||
TypeError,
|
TypeError,
|
||||||
|
|
||||||
Warning
|
Warning
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,22 +71,39 @@ public:
|
|||||||
m_typeName = "Warning";
|
m_typeName = "Warning";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
m_typeName = "Error";
|
solAssert(false, "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Type const type() { return m_type; } const
|
Type type() const { return m_type; }
|
||||||
std::string const& typeName() const { return m_typeName; }
|
std::string const& typeName() const { return m_typeName; }
|
||||||
|
|
||||||
|
|
||||||
|
/// helper functions
|
||||||
|
static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type)
|
||||||
|
{
|
||||||
|
for (auto e: _list)
|
||||||
|
{
|
||||||
|
if(e->type() == _type)
|
||||||
|
return e.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
static bool containsOnlyWarnings(ErrorList const& _list)
|
||||||
|
{
|
||||||
|
for (auto e: _list)
|
||||||
|
{
|
||||||
|
if(e->type() != Type::Warning)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
Type m_type;
|
Type m_type;
|
||||||
std::string m_typeName;
|
std::string m_typeName;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompilerError: virtual Exception {};
|
|
||||||
struct InternalCompilerError: virtual Exception {};
|
|
||||||
struct FatalError: virtual Exception {};
|
|
||||||
|
|
||||||
using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;
|
using errorSourceLocationInfo = std::pair<std::string, SourceLocation>;
|
||||||
|
|
||||||
@ -96,7 +119,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using ErrorList = std::vector<std::shared_ptr<Error const>>;
|
|
||||||
using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
|
using errinfo_sourceLocation = boost::error_info<struct tag_sourceLocation, SourceLocation>;
|
||||||
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
|
using errinfo_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>;
|
||||||
|
|
||||||
|
@ -42,81 +42,105 @@ NameAndTypeResolver::NameAndTypeResolver(
|
|||||||
m_scopes[nullptr].registerDeclaration(*declaration);
|
m_scopes[nullptr].registerDeclaration(*declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit)
|
bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit)
|
||||||
{
|
{
|
||||||
// The helper registers all declarations in m_scopes as a side-effect of its construction.
|
// The helper registers all declarations in m_scopes as a side-effect of its construction.
|
||||||
DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit);
|
try
|
||||||
|
{
|
||||||
|
DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errors);
|
||||||
|
}
|
||||||
|
catch (fatalError)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
||||||
{
|
{
|
||||||
m_currentScope = &m_scopes[nullptr];
|
try
|
||||||
|
|
||||||
for (ASTPointer<InheritanceSpecifier> const& baseContract: _contract.baseContracts())
|
|
||||||
ReferencesResolver resolver(*baseContract, *this, &_contract, nullptr);
|
|
||||||
|
|
||||||
m_currentScope = &m_scopes[&_contract];
|
|
||||||
|
|
||||||
linearizeBaseContracts(_contract);
|
|
||||||
std::vector<ContractDefinition const*> properBases(
|
|
||||||
++_contract.annotation().linearizedBaseContracts.begin(),
|
|
||||||
_contract.annotation().linearizedBaseContracts.end()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (ContractDefinition const* base: properBases)
|
|
||||||
importInheritedScope(*base);
|
|
||||||
|
|
||||||
for (ASTPointer<StructDefinition> const& structDef: _contract.definedStructs())
|
|
||||||
ReferencesResolver resolver(*structDef, *this, &_contract, nullptr);
|
|
||||||
for (ASTPointer<EnumDefinition> const& enumDef: _contract.definedEnums())
|
|
||||||
ReferencesResolver resolver(*enumDef, *this, &_contract, nullptr);
|
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables())
|
|
||||||
ReferencesResolver resolver(*variable, *this, &_contract, nullptr);
|
|
||||||
for (ASTPointer<EventDefinition> const& event: _contract.events())
|
|
||||||
ReferencesResolver resolver(*event, *this, &_contract, nullptr);
|
|
||||||
|
|
||||||
// these can contain code, only resolve parameters for now
|
|
||||||
for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
|
|
||||||
{
|
{
|
||||||
m_currentScope = &m_scopes[modifier.get()];
|
m_currentScope = &m_scopes[nullptr];
|
||||||
ReferencesResolver resolver(*modifier, *this, &_contract, nullptr);
|
|
||||||
}
|
for (ASTPointer<InheritanceSpecifier> const& baseContract: _contract.baseContracts())
|
||||||
for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
|
ReferencesResolver resolver(*baseContract, *this, &_contract, nullptr);
|
||||||
{
|
|
||||||
m_currentScope = &m_scopes[function.get()];
|
m_currentScope = &m_scopes[&_contract];
|
||||||
ReferencesResolver referencesResolver(
|
|
||||||
*function,
|
linearizeBaseContracts(_contract);
|
||||||
*this,
|
std::vector<ContractDefinition const*> properBases(
|
||||||
&_contract,
|
++_contract.annotation().linearizedBaseContracts.begin(),
|
||||||
function->returnParameterList().get()
|
_contract.annotation().linearizedBaseContracts.end()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
m_currentScope = &m_scopes[&_contract];
|
for (ContractDefinition const* base: properBases)
|
||||||
|
importInheritedScope(*base);
|
||||||
|
|
||||||
// now resolve references inside the code
|
for (ASTPointer<StructDefinition> const& structDef: _contract.definedStructs())
|
||||||
for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
|
ReferencesResolver resolver(*structDef, *this, &_contract, nullptr);
|
||||||
{
|
for (ASTPointer<EnumDefinition> const& enumDef: _contract.definedEnums())
|
||||||
m_currentScope = &m_scopes[modifier.get()];
|
ReferencesResolver resolver(*enumDef, *this, &_contract, nullptr);
|
||||||
ReferencesResolver resolver(*modifier, *this, &_contract, nullptr, true);
|
for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables())
|
||||||
|
ReferencesResolver resolver(*variable, *this, &_contract, nullptr);
|
||||||
|
for (ASTPointer<EventDefinition> const& event: _contract.events())
|
||||||
|
ReferencesResolver resolver(*event, *this, &_contract, nullptr);
|
||||||
|
|
||||||
|
// these can contain code, only resolve parameters for now
|
||||||
|
for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
|
||||||
|
{
|
||||||
|
m_currentScope = &m_scopes[modifier.get()];
|
||||||
|
ReferencesResolver resolver(*modifier, *this, &_contract, nullptr);
|
||||||
|
}
|
||||||
|
for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
|
||||||
|
{
|
||||||
|
m_currentScope = &m_scopes[function.get()];
|
||||||
|
ReferencesResolver referencesResolver(
|
||||||
|
*function,
|
||||||
|
*this,
|
||||||
|
&_contract,
|
||||||
|
function->returnParameterList().get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentScope = &m_scopes[&_contract];
|
||||||
|
|
||||||
|
// now resolve references inside the code
|
||||||
|
for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers())
|
||||||
|
{
|
||||||
|
m_currentScope = &m_scopes[modifier.get()];
|
||||||
|
ReferencesResolver resolver(*modifier, *this, &_contract, nullptr, true);
|
||||||
|
}
|
||||||
|
for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
|
||||||
|
{
|
||||||
|
m_currentScope = &m_scopes[function.get()];
|
||||||
|
ReferencesResolver referencesResolver(
|
||||||
|
*function,
|
||||||
|
*this,
|
||||||
|
&_contract,
|
||||||
|
function->returnParameterList().get(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (ASTPointer<FunctionDefinition> const& function: _contract.definedFunctions())
|
catch (fatalError const& _e)
|
||||||
{
|
{
|
||||||
m_currentScope = &m_scopes[function.get()];
|
return false;
|
||||||
ReferencesResolver referencesResolver(
|
|
||||||
*function,
|
|
||||||
*this,
|
|
||||||
&_contract,
|
|
||||||
function->returnParameterList().get(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
|
bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
|
||||||
{
|
{
|
||||||
m_scopes[nullptr].registerDeclaration(_declaration, false, true);
|
try
|
||||||
solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope.");
|
{
|
||||||
|
m_scopes[nullptr].registerDeclaration(_declaration, false, true);
|
||||||
|
solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope.");
|
||||||
|
}
|
||||||
|
catch(fatalError _error)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
|
vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
|
||||||
@ -164,11 +188,8 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
|
|||||||
FunctionType functionType(functionDefinition);
|
FunctionType functionType(functionDefinition);
|
||||||
for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes())
|
for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes())
|
||||||
if (!parameter)
|
if (!parameter)
|
||||||
BOOST_THROW_EXCEPTION(
|
reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context");
|
||||||
Error(Error::Type::DeclarationError) <<
|
|
||||||
errinfo_sourceLocation(_identifier.location()) <<
|
|
||||||
errinfo_comment("Function type can not be used in this context")
|
|
||||||
);
|
|
||||||
if (uniqueFunctions.end() == find_if(
|
if (uniqueFunctions.end() == find_if(
|
||||||
uniqueFunctions.begin(),
|
uniqueFunctions.begin(),
|
||||||
uniqueFunctions.end(),
|
uniqueFunctions.end(),
|
||||||
@ -194,7 +215,7 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base)
|
|||||||
m_currentScope->registerDeclaration(*declaration);
|
m_currentScope->registerDeclaration(*declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const
|
void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
|
||||||
{
|
{
|
||||||
// order in the lists is from derived to base
|
// order in the lists is from derived to base
|
||||||
// list of lists to linearize, the last element is the list of direct bases
|
// list of lists to linearize, the last element is the list of direct bases
|
||||||
@ -204,19 +225,19 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract)
|
|||||||
Identifier const& baseName = baseSpecifier->name();
|
Identifier const& baseName = baseSpecifier->name();
|
||||||
auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration);
|
auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration);
|
||||||
if (!base)
|
if (!base)
|
||||||
BOOST_THROW_EXCEPTION(baseName.createTypeError("Contract expected."));
|
reportFatalTypeError(baseName.createTypeError("Contract expected."));
|
||||||
// "push_front" has the effect that bases mentioned later can overwrite members of bases
|
// "push_front" has the effect that bases mentioned later can overwrite members of bases
|
||||||
// mentioned earlier
|
// mentioned earlier
|
||||||
input.back().push_front(base);
|
input.back().push_front(base);
|
||||||
vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts;
|
vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts;
|
||||||
if (basesBases.empty())
|
if (basesBases.empty())
|
||||||
BOOST_THROW_EXCEPTION(baseName.createTypeError("Definition of base has to precede definition of derived contract"));
|
reportFatalTypeError(baseName.createTypeError("Definition of base has to precede definition of derived contract"));
|
||||||
input.push_front(list<ContractDefinition const*>(basesBases.begin(), basesBases.end()));
|
input.push_front(list<ContractDefinition const*>(basesBases.begin(), basesBases.end()));
|
||||||
}
|
}
|
||||||
input.back().push_front(&_contract);
|
input.back().push_front(&_contract);
|
||||||
vector<ContractDefinition const*> result = cThreeMerge(input);
|
vector<ContractDefinition const*> result = cThreeMerge(input);
|
||||||
if (result.empty())
|
if (result.empty())
|
||||||
BOOST_THROW_EXCEPTION(_contract.createTypeError("Linearization of inheritance graph impossible"));
|
reportFatalTypeError(_contract.createTypeError("Linearization of inheritance graph impossible"));
|
||||||
_contract.annotation().linearizedBaseContracts = result;
|
_contract.annotation().linearizedBaseContracts = result;
|
||||||
_contract.annotation().contractDependencies.insert(result.begin() + 1, result.end());
|
_contract.annotation().contractDependencies.insert(result.begin() + 1, result.end());
|
||||||
}
|
}
|
||||||
@ -272,9 +293,53 @@ vector<_T const*> NameAndTypeResolver::cThreeMerge(list<list<_T const*>>& _toMer
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, DeclarationContainer>& _scopes,
|
void NameAndTypeResolver::reportDeclarationError(
|
||||||
ASTNode& _astRoot):
|
SourceLocation _sourceLoction,
|
||||||
m_scopes(_scopes), m_currentScope(nullptr)
|
string const& _description,
|
||||||
|
SourceLocation _secondarySourceLocation = SourceLocation(),
|
||||||
|
string const& _secondaryDescription = ""
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto err = make_shared<Error>(Error::Type::DeclarationError); // todo remove Error?
|
||||||
|
*err <<
|
||||||
|
errinfo_sourceLocation(_sourceLoction) <<
|
||||||
|
errinfo_comment(_description) <<
|
||||||
|
errinfo_secondarySourceLocation(
|
||||||
|
SecondarySourceLocation().append(_secondaryDescription, _secondarySourceLocation)
|
||||||
|
);
|
||||||
|
|
||||||
|
m_errors.push_back(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameAndTypeResolver::reportFatalDeclarationError(
|
||||||
|
SourceLocation _sourceLoction,
|
||||||
|
string _description
|
||||||
|
)
|
||||||
|
{
|
||||||
|
reportDeclarationError(_sourceLoction, _description);
|
||||||
|
BOOST_THROW_EXCEPTION(fatalError());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameAndTypeResolver::reportTypeError(Error _e)
|
||||||
|
{
|
||||||
|
m_errors.push_back(make_shared<Error>(_e));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NameAndTypeResolver::reportFatalTypeError(Error _e)
|
||||||
|
{
|
||||||
|
reportTypeError(_e);
|
||||||
|
BOOST_THROW_EXCEPTION(fatalError());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DeclarationRegistrationHelper::DeclarationRegistrationHelper(
|
||||||
|
map<ASTNode const*, DeclarationContainer>& _scopes,
|
||||||
|
ASTNode& _astRoot,
|
||||||
|
ErrorList& _errors
|
||||||
|
):
|
||||||
|
m_scopes(_scopes),
|
||||||
|
m_currentScope(nullptr),
|
||||||
|
m_errors(_errors)
|
||||||
{
|
{
|
||||||
_astRoot.accept(*this);
|
_astRoot.accept(*this);
|
||||||
}
|
}
|
||||||
@ -409,13 +474,11 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
|
|||||||
secondDeclarationLocation = _declaration.location();
|
secondDeclarationLocation = _declaration.location();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_THROW_EXCEPTION(
|
declarationError(
|
||||||
Error(Error::Type::DeclarationError) <<
|
secondDeclarationLocation,
|
||||||
errinfo_sourceLocation(secondDeclarationLocation) <<
|
"Identifier already declared.",
|
||||||
errinfo_comment("Identifier already declared.") <<
|
firstDeclarationLocation,
|
||||||
errinfo_secondarySourceLocation(
|
"The previous declaration is here:"
|
||||||
SecondarySourceLocation().append("The previous declaration is here:", firstDeclarationLocation)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,5 +503,32 @@ string DeclarationRegistrationHelper::currentCanonicalName() const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeclarationRegistrationHelper::declarationError(
|
||||||
|
SourceLocation _sourceLoction,
|
||||||
|
string const& _description,
|
||||||
|
SourceLocation _secondarySourceLocation = SourceLocation(),
|
||||||
|
string const& _secondaryDescription = ""
|
||||||
|
)
|
||||||
|
{
|
||||||
|
auto err = make_shared<Error>(Error::Type::DeclarationError);
|
||||||
|
*err <<
|
||||||
|
errinfo_sourceLocation(_sourceLoction) <<
|
||||||
|
errinfo_comment(_description) <<
|
||||||
|
errinfo_secondarySourceLocation(
|
||||||
|
SecondarySourceLocation().append(_secondaryDescription, _secondarySourceLocation)
|
||||||
|
);
|
||||||
|
|
||||||
|
m_errors.push_back(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeclarationRegistrationHelper::fatalDeclarationError(
|
||||||
|
SourceLocation _sourceLoction,
|
||||||
|
string const& _description
|
||||||
|
)
|
||||||
|
{
|
||||||
|
declarationError(_sourceLoction, _description);
|
||||||
|
BOOST_THROW_EXCEPTION(fatalError());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,15 @@ class NameAndTypeResolver: private boost::noncopyable
|
|||||||
public:
|
public:
|
||||||
NameAndTypeResolver(std::vector<Declaration const*> const& _globals, ErrorList& _errors);
|
NameAndTypeResolver(std::vector<Declaration const*> const& _globals, ErrorList& _errors);
|
||||||
/// Registers all declarations found in the source unit.
|
/// Registers all declarations found in the source unit.
|
||||||
void registerDeclarations(SourceUnit& _sourceUnit);
|
/// @returns false in case of type error.
|
||||||
|
bool registerDeclarations(SourceUnit& _sourceUnit);
|
||||||
/// Resolves all names and types referenced from the given contract.
|
/// Resolves all names and types referenced from the given contract.
|
||||||
void resolveNamesAndTypes(ContractDefinition& _contract);
|
/// @returns false in case of type error.
|
||||||
|
bool resolveNamesAndTypes(ContractDefinition& _contract);
|
||||||
/// Updates the given global declaration (used for "this"). Not to be used with declarations
|
/// Updates the given global declaration (used for "this"). Not to be used with declarations
|
||||||
/// that create their own scope.
|
/// that create their own scope.
|
||||||
void updateDeclaration(Declaration const& _declaration);
|
/// @returns false in case of type error.
|
||||||
|
bool updateDeclaration(Declaration const& _declaration);
|
||||||
|
|
||||||
/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
|
/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
|
||||||
/// the global scope is used (i.e. the one containing only the contract).
|
/// the global scope is used (i.e. the one containing only the contract).
|
||||||
@ -66,7 +69,7 @@ public:
|
|||||||
Declaration const* pathFromCurrentScope(std::vector<ASTString> const& _path, bool _recursive = true) const;
|
Declaration const* pathFromCurrentScope(std::vector<ASTString> const& _path, bool _recursive = true) const;
|
||||||
|
|
||||||
/// returns the vector of declarations without repetitions
|
/// returns the vector of declarations without repetitions
|
||||||
static std::vector<Declaration const*> cleanedDeclarations(
|
std::vector<Declaration const*> cleanedDeclarations(
|
||||||
Identifier const& _identifier,
|
Identifier const& _identifier,
|
||||||
std::vector<Declaration const*> const& _declarations
|
std::vector<Declaration const*> const& _declarations
|
||||||
);
|
);
|
||||||
@ -78,8 +81,8 @@ private:
|
|||||||
/// into the current scope if they are not present already.
|
/// into the current scope if they are not present already.
|
||||||
void importInheritedScope(ContractDefinition const& _base);
|
void importInheritedScope(ContractDefinition const& _base);
|
||||||
|
|
||||||
/// Computes "C3-Linearization" of base contracts and stores it inside the contract.
|
/// Computes "C3-Linearization" of base contracts and stores it inside the contract. Reports errors if any
|
||||||
void linearizeBaseContracts(ContractDefinition& _contract) const;
|
void linearizeBaseContracts(ContractDefinition& _contract);
|
||||||
/// Computes the C3-merge of the given list of lists of bases.
|
/// Computes the C3-merge of the given list of lists of bases.
|
||||||
/// @returns the linearized vector or an empty vector if linearization is not possible.
|
/// @returns the linearized vector or an empty vector if linearization is not possible.
|
||||||
template <class _T>
|
template <class _T>
|
||||||
@ -90,6 +93,21 @@ private:
|
|||||||
/// not contain code.
|
/// not contain code.
|
||||||
std::map<ASTNode const*, DeclarationContainer> m_scopes;
|
std::map<ASTNode const*, DeclarationContainer> m_scopes;
|
||||||
|
|
||||||
|
// creates the Declaration error and adds it in the errors list
|
||||||
|
void reportDeclarationError(
|
||||||
|
SourceLocation _sourceLoction,
|
||||||
|
std::string const& _description,
|
||||||
|
SourceLocation _secondarySourceLocation,
|
||||||
|
std::string const& _secondaryDescription
|
||||||
|
);
|
||||||
|
// creates the Declaration error and adds it in the errors list and throws FatalError
|
||||||
|
void reportFatalDeclarationError(SourceLocation _sourceLoction, std::string _description);
|
||||||
|
|
||||||
|
// creates the Declaration error and adds it in the errors list
|
||||||
|
void reportTypeError(Error _e);
|
||||||
|
// creates the Declaration error and adds it in the errors list and throws FatalError
|
||||||
|
void reportFatalTypeError(Error _e);
|
||||||
|
|
||||||
DeclarationContainer* m_currentScope = nullptr;
|
DeclarationContainer* m_currentScope = nullptr;
|
||||||
ErrorList& m_errors;
|
ErrorList& m_errors;
|
||||||
};
|
};
|
||||||
@ -101,7 +119,7 @@ private:
|
|||||||
class DeclarationRegistrationHelper: private ASTVisitor
|
class DeclarationRegistrationHelper: private ASTVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot);
|
DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot, ErrorList& _errors);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool visit(ContractDefinition& _contract) override;
|
bool visit(ContractDefinition& _contract) override;
|
||||||
@ -126,10 +144,20 @@ private:
|
|||||||
|
|
||||||
/// @returns the canonical name of the current scope.
|
/// @returns the canonical name of the current scope.
|
||||||
std::string currentCanonicalName() const;
|
std::string currentCanonicalName() const;
|
||||||
|
// creates the Declaration error and adds it in the errors list
|
||||||
|
void declarationError(
|
||||||
|
SourceLocation _sourceLoction,
|
||||||
|
std::string const& _description,
|
||||||
|
SourceLocation _secondarySourceLocation,
|
||||||
|
std::string const& _secondaryDescription
|
||||||
|
);
|
||||||
|
// creates the Declaration error and adds it in the errors list and throws FatalError
|
||||||
|
void fatalDeclarationError(SourceLocation _sourceLoction, std::string const& _description);
|
||||||
|
|
||||||
std::map<ASTNode const*, DeclarationContainer>& m_scopes;
|
std::map<ASTNode const*, DeclarationContainer>& m_scopes;
|
||||||
Declaration const* m_currentScope;
|
Declaration const* m_currentScope;
|
||||||
VariableScope* m_currentFunction;
|
VariableScope* m_currentFunction;
|
||||||
|
ErrorList& m_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,25 +66,35 @@ private:
|
|||||||
|
|
||||||
ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
||||||
{
|
{
|
||||||
m_scanner = _scanner;
|
try{
|
||||||
ASTNodeFactory nodeFactory(*this);
|
m_scanner = _scanner;
|
||||||
vector<ASTPointer<ASTNode>> nodes;
|
ASTNodeFactory nodeFactory(*this);
|
||||||
while (m_scanner->currentToken() != Token::EOS)
|
vector<ASTPointer<ASTNode>> nodes;
|
||||||
{
|
while (m_scanner->currentToken() != Token::EOS)
|
||||||
switch (auto token = m_scanner->currentToken())
|
|
||||||
{
|
{
|
||||||
case Token::Import:
|
switch (auto token = m_scanner->currentToken())
|
||||||
nodes.push_back(parseImportDirective());
|
{
|
||||||
break;
|
case Token::Import:
|
||||||
case Token::Contract:
|
nodes.push_back(parseImportDirective());
|
||||||
case Token::Library:
|
break;
|
||||||
nodes.push_back(parseContractDefinition(token == Token::Library));
|
case Token::Contract:
|
||||||
break;
|
case Token::Library:
|
||||||
default:
|
nodes.push_back(parseContractDefinition(token == Token::Library));
|
||||||
BOOST_THROW_EXCEPTION(createParserError(std::string("Expected import directive or contract definition.")));
|
break;
|
||||||
|
default:
|
||||||
|
fatalParserError(std::string("Expected import directive or contract definition."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nodeFactory.createNode<SourceUnit>(nodes);
|
||||||
|
}
|
||||||
|
catch(fatalError const& _error)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
catch(Exception const& _e)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return nodeFactory.createNode<SourceUnit>(nodes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const string> const& Parser::sourceName() const
|
std::shared_ptr<const string> const& Parser::sourceName() const
|
||||||
@ -107,7 +117,7 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
|
|||||||
ASTNodeFactory nodeFactory(*this);
|
ASTNodeFactory nodeFactory(*this);
|
||||||
expectToken(Token::Import);
|
expectToken(Token::Import);
|
||||||
if (m_scanner->currentToken() != Token::StringLiteral)
|
if (m_scanner->currentToken() != Token::StringLiteral)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected string literal (URL)."));
|
fatalParserError(std::string("Expected string literal (URL)."));
|
||||||
ASTPointer<ASTString> url = getLiteralAndAdvance();
|
ASTPointer<ASTString> url = getLiteralAndAdvance();
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
@ -165,7 +175,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary)
|
|||||||
else if (currentTokenValue == Token::Event)
|
else if (currentTokenValue == Token::Event)
|
||||||
events.push_back(parseEventDefinition());
|
events.push_back(parseEventDefinition());
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
|
fatalParserError(std::string("Function, variable, struct or modifier declaration expected."));
|
||||||
}
|
}
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBrace);
|
expectToken(Token::RBrace);
|
||||||
@ -249,7 +259,7 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const*
|
|||||||
else if (Token::isVisibilitySpecifier(token))
|
else if (Token::isVisibilitySpecifier(token))
|
||||||
{
|
{
|
||||||
if (visibility != Declaration::Visibility::Default)
|
if (visibility != Declaration::Visibility::Default)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Multiple visibility specifiers."));
|
fatalParserError(std::string("Multiple visibility specifiers."));
|
||||||
visibility = parseVisibilitySpecifier(token);
|
visibility = parseVisibilitySpecifier(token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -326,7 +336,7 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
|||||||
break;
|
break;
|
||||||
expectToken(Token::Comma);
|
expectToken(Token::Comma);
|
||||||
if (m_scanner->currentToken() != Token::Identifier)
|
if (m_scanner->currentToken() != Token::Identifier)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','"));
|
fatalParserError(std::string("Expected Identifier after ','"));
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
@ -362,7 +372,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token))
|
if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token))
|
||||||
{
|
{
|
||||||
if (visibility != Declaration::Visibility::Default)
|
if (visibility != Declaration::Visibility::Default)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Visibility already specified."));
|
fatalParserError(std::string("Visibility already specified."));
|
||||||
visibility = parseVisibilitySpecifier(token);
|
visibility = parseVisibilitySpecifier(token);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -374,9 +384,9 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token))
|
else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token))
|
||||||
{
|
{
|
||||||
if (location != VariableDeclaration::Location::Default)
|
if (location != VariableDeclaration::Location::Default)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Location already specified."));
|
fatalParserError(std::string("Location already specified."));
|
||||||
if (!type)
|
if (!type)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Location specifier needs explicit type name."));
|
fatalParserError(std::string("Location specifier needs explicit type name."));
|
||||||
location = (
|
location = (
|
||||||
token == Token::Memory ?
|
token == Token::Memory ?
|
||||||
VariableDeclaration::Location::Memory :
|
VariableDeclaration::Location::Memory :
|
||||||
@ -513,7 +523,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
else if (token == Token::Var)
|
else if (token == Token::Var)
|
||||||
{
|
{
|
||||||
if (!_allowVar)
|
if (!_allowVar)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected explicit type name."));
|
fatalParserError(std::string("Expected explicit type name."));
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else if (token == Token::Mapping)
|
else if (token == Token::Mapping)
|
||||||
@ -532,7 +542,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
type = nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
|
type = nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected type name"));
|
fatalParserError(std::string("Expected type name"));
|
||||||
|
|
||||||
if (type)
|
if (type)
|
||||||
// Parse "[...]" postfixes for arrays.
|
// Parse "[...]" postfixes for arrays.
|
||||||
@ -555,7 +565,7 @@ ASTPointer<Mapping> Parser::parseMapping()
|
|||||||
expectToken(Token::Mapping);
|
expectToken(Token::Mapping);
|
||||||
expectToken(Token::LParen);
|
expectToken(Token::LParen);
|
||||||
if (!Token::isElementaryTypeName(m_scanner->currentToken()))
|
if (!Token::isElementaryTypeName(m_scanner->currentToken()))
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected elementary type name for mapping key type"));
|
fatalParserError(std::string("Expected elementary type name for mapping key type"));
|
||||||
ASTPointer<ElementaryTypeName> keyType;
|
ASTPointer<ElementaryTypeName> keyType;
|
||||||
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->currentToken());
|
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->currentToken());
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -1011,7 +1021,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected primary expression."));
|
fatalParserError(std::string("Expected primary expression."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return expression;
|
return expression;
|
||||||
@ -1122,7 +1132,7 @@ ASTPointer<Expression> Parser::expressionFromIndexAccessStructure(
|
|||||||
void Parser::expectToken(Token::Value _value)
|
void Parser::expectToken(Token::Value _value)
|
||||||
{
|
{
|
||||||
if (m_scanner->currentToken() != _value)
|
if (m_scanner->currentToken() != _value)
|
||||||
BOOST_THROW_EXCEPTION(createParserError(string("Expected token ") + string(Token::name(_value))));
|
fatalParserError(std::string(string("Expected token ") + string(Token::name(_value))));
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1130,7 +1140,7 @@ Token::Value Parser::expectAssignmentOperator()
|
|||||||
{
|
{
|
||||||
Token::Value op = m_scanner->currentToken();
|
Token::Value op = m_scanner->currentToken();
|
||||||
if (!Token::isAssignmentOp(op))
|
if (!Token::isAssignmentOp(op))
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected assignment operator"));
|
fatalParserError(std::string("Expected assignment operator"));
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
@ -1138,7 +1148,7 @@ Token::Value Parser::expectAssignmentOperator()
|
|||||||
ASTPointer<ASTString> Parser::expectIdentifierToken()
|
ASTPointer<ASTString> Parser::expectIdentifierToken()
|
||||||
{
|
{
|
||||||
if (m_scanner->currentToken() != Token::Identifier)
|
if (m_scanner->currentToken() != Token::Identifier)
|
||||||
BOOST_THROW_EXCEPTION(createParserError("Expected identifier"));
|
fatalParserError(std::string("Expected identifier"));
|
||||||
return getLiteralAndAdvance();
|
return getLiteralAndAdvance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1156,13 +1166,21 @@ ASTPointer<ParameterList> Parser::createEmptyParameterList()
|
|||||||
return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
|
return nodeFactory.createNode<ParameterList>(vector<ASTPointer<VariableDeclaration>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
Error Parser::createParserError(string const& _description) const
|
void Parser::parserError(string const& _description)
|
||||||
{
|
{
|
||||||
return Error(Error::Type::ParserError) <<
|
auto err = make_shared<Error>(Error::Type::ParserError);
|
||||||
errinfo_sourceLocation(SourceLocation(position(), position(), sourceName())) <<
|
*err <<
|
||||||
errinfo_comment(_description);
|
errinfo_sourceLocation(SourceLocation(position(), position(), sourceName())) <<
|
||||||
|
errinfo_comment(_description);
|
||||||
|
|
||||||
|
m_errors.push_back(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::fatalParserError(string const& _description)
|
||||||
|
{
|
||||||
|
parserError(_description);
|
||||||
|
BOOST_THROW_EXCEPTION(fatalError());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,8 @@ class Scanner;
|
|||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Parser() {}
|
Parser(ErrorList& errors):
|
||||||
|
m_errors(errors){};
|
||||||
|
|
||||||
ASTPointer<SourceUnit> parse(std::shared_ptr<Scanner> const& _scanner);
|
ASTPointer<SourceUnit> parse(std::shared_ptr<Scanner> const& _scanner);
|
||||||
std::shared_ptr<std::string const> const& sourceName() const;
|
std::shared_ptr<std::string const> const& sourceName() const;
|
||||||
@ -145,13 +146,19 @@ private:
|
|||||||
/// Creates an empty ParameterList at the current location (used if parameters can be omitted).
|
/// Creates an empty ParameterList at the current location (used if parameters can be omitted).
|
||||||
ASTPointer<ParameterList> createEmptyParameterList();
|
ASTPointer<ParameterList> createEmptyParameterList();
|
||||||
|
|
||||||
/// Creates a @ref ParserError exception and annotates it with the current position and the
|
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||||
/// given @a _description.
|
/// given @a _description.
|
||||||
Error createParserError(std::string const& _description) const;
|
void parserError(std::string const& _description);
|
||||||
|
|
||||||
|
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||||
|
/// given @a _description. Throws the FatalError.
|
||||||
|
void fatalParserError(std::string const& _description);
|
||||||
|
|
||||||
std::shared_ptr<Scanner> m_scanner;
|
std::shared_ptr<Scanner> m_scanner;
|
||||||
/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.
|
/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.
|
||||||
bool m_insideModifier = false;
|
bool m_insideModifier = false;
|
||||||
|
/// The reference to the list of errors and warning to add errors/warnings during parsing
|
||||||
|
ErrorList& m_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,24 +36,26 @@ bool TypeChecker::checkTypeRequirements(const ContractDefinition& _contract)
|
|||||||
{
|
{
|
||||||
visit(_contract);
|
visit(_contract);
|
||||||
}
|
}
|
||||||
catch (FatalError const&)
|
catch (fatalError const&)
|
||||||
{
|
{
|
||||||
// We got a fatal error which required to stop further type checking, but we can
|
// We got a fatal error which required to stop further type checking, but we can
|
||||||
// continue normally from here.
|
// continue normally from here.
|
||||||
if (m_errors.empty())
|
if (m_errors.empty())
|
||||||
throw; // Something is weird here, rather throw again.
|
throw; // Something is weird here, rather throw again.
|
||||||
}
|
}
|
||||||
bool success = true;
|
|
||||||
for (auto const& it: m_errors)
|
return Error::containsOnlyWarnings(m_errors);
|
||||||
{
|
// bool success = true;
|
||||||
Error const& e = dynamic_cast<Error const&>(it.get());
|
// for (auto const& it: m_errors)
|
||||||
if (e.type() != Error::Type::Warning)
|
// {
|
||||||
{
|
// auto e = dynamic_cast<Error const*>(it.get());
|
||||||
success = false;
|
// if (e->type() != Error::Type::Warning)
|
||||||
break;
|
// {
|
||||||
}
|
// success = false;
|
||||||
}
|
// break;
|
||||||
return success;
|
// }
|
||||||
|
// }
|
||||||
|
// return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer const& TypeChecker::type(Expression const& _expression) const
|
TypePointer const& TypeChecker::type(Expression const& _expression) const
|
||||||
@ -1255,7 +1257,7 @@ void TypeChecker::requireLValue(Expression const& _expression)
|
|||||||
|
|
||||||
void TypeChecker::typeError(ASTNode const& _node, string const& _description)
|
void TypeChecker::typeError(ASTNode const& _node, string const& _description)
|
||||||
{
|
{
|
||||||
auto err = make_shared<Error>(Error(Error::Type::TypeError));;
|
auto err = make_shared<Error>(Error::Type::TypeError);
|
||||||
*err <<
|
*err <<
|
||||||
errinfo_sourceLocation(_node.location()) <<
|
errinfo_sourceLocation(_node.location()) <<
|
||||||
errinfo_comment(_description);
|
errinfo_comment(_description);
|
||||||
@ -1266,5 +1268,5 @@ void TypeChecker::typeError(ASTNode const& _node, string const& _description)
|
|||||||
void TypeChecker::fatalTypeError(ASTNode const& _node, string const& _description)
|
void TypeChecker::fatalTypeError(ASTNode const& _node, string const& _description)
|
||||||
{
|
{
|
||||||
typeError(_node, _description);
|
typeError(_node, _description);
|
||||||
BOOST_THROW_EXCEPTION(FatalError());
|
BOOST_THROW_EXCEPTION(fatalError());
|
||||||
}
|
}
|
||||||
|
@ -42,26 +42,26 @@ namespace solidity
|
|||||||
class TypeChecker: private ASTConstVisitor
|
class TypeChecker: private ASTConstVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/// @_errors the reference to the list of errors and warnings to add them found during type checking.
|
||||||
|
TypeChecker(ErrorList& _errors): m_errors(_errors) {}
|
||||||
|
|
||||||
/// Performs type checking on the given contract and all of its sub-nodes.
|
/// Performs type checking on the given contract and all of its sub-nodes.
|
||||||
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
|
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
|
||||||
bool checkTypeRequirements(ContractDefinition const& _contract);
|
bool checkTypeRequirements(ContractDefinition const& _contract);
|
||||||
|
|
||||||
/// @returns the list of errors and warnings found during type checking.
|
|
||||||
ErrorList const& errors() const { return m_errors; }
|
|
||||||
|
|
||||||
/// @returns the type of an expression and asserts that it is present.
|
/// @returns the type of an expression and asserts that it is present.
|
||||||
TypePointer const& type(Expression const& _expression) const;
|
TypePointer const& type(Expression const& _expression) const;
|
||||||
/// @returns the type of the given variable and throws if the type is not present
|
/// @returns the type of the given variable and throws if the type is not present
|
||||||
/// (this can happen for variables with non-explicit types before their types are resolved)
|
/// (this can happen for variables with non-explicit types before their types are resolved)
|
||||||
TypePointer const& type(VariableDeclaration const& _variable) const;
|
TypePointer const& type(VariableDeclaration const& _variable) const;
|
||||||
|
|
||||||
|
private:
|
||||||
/// Adds a new error to the list of errors.
|
/// Adds a new error to the list of errors.
|
||||||
void typeError(ASTNode const& _node, std::string const& _description);
|
void typeError(ASTNode const& _node, std::string const& _description);
|
||||||
|
|
||||||
/// Adds a new error to the list of errors and throws to abort type checking.
|
/// Adds a new error to the list of errors and throws to abort type checking.
|
||||||
void fatalTypeError(ASTNode const& _node, std::string const& _description);
|
void fatalTypeError(ASTNode const& _node, std::string const& _description);
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool visit(ContractDefinition const& _contract) override;
|
virtual bool visit(ContractDefinition const& _contract) override;
|
||||||
/// Checks that two functions defined in this contract with the same name have different
|
/// Checks that two functions defined in this contract with the same name have different
|
||||||
/// arguments and that there is at most one constructor.
|
/// arguments and that there is at most one constructor.
|
||||||
@ -114,7 +114,7 @@ private:
|
|||||||
/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.
|
/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.
|
||||||
void requireLValue(Expression const& _expression);
|
void requireLValue(Expression const& _expression);
|
||||||
|
|
||||||
ErrorList m_errors;
|
ErrorList& m_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -496,7 +496,7 @@ bool CommandLineInterface::processInput()
|
|||||||
SourceReferenceFormatter::printExceptionInformation(
|
SourceReferenceFormatter::printExceptionInformation(
|
||||||
cerr,
|
cerr,
|
||||||
*error,
|
*error,
|
||||||
(dynamic_pointer_cast<Warning const>(error)) ? "Warning" : "Error", *m_compiler
|
(error->type() == Error::Type::Warning) ? "Warning" : "Error", *m_compiler
|
||||||
);
|
);
|
||||||
if (!successful)
|
if (!successful)
|
||||||
return false;
|
return false;
|
||||||
|
@ -48,21 +48,29 @@ namespace
|
|||||||
|
|
||||||
eth::AssemblyItems compileContract(const string& _sourceCode)
|
eth::AssemblyItems compileContract(const string& _sourceCode)
|
||||||
{
|
{
|
||||||
Parser parser;
|
ErrorList errors;
|
||||||
|
Parser parser(errors);
|
||||||
ASTPointer<SourceUnit> sourceUnit;
|
ASTPointer<SourceUnit> sourceUnit;
|
||||||
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
|
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
|
||||||
NameAndTypeResolver resolver({});
|
BOOST_CHECK(!!sourceUnit);
|
||||||
|
|
||||||
|
NameAndTypeResolver resolver({}, errors);
|
||||||
|
solAssert(Error::containsOnlyWarnings(errors), "");
|
||||||
resolver.registerDeclarations(*sourceUnit);
|
resolver.registerDeclarations(*sourceUnit);
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
|
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
|
||||||
|
if (!Error::containsOnlyWarnings(errors))
|
||||||
|
return AssemblyItems();
|
||||||
}
|
}
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
TypeChecker checker;
|
TypeChecker checker(errors);
|
||||||
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract));
|
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract));
|
||||||
|
if (!Error::containsOnlyWarnings(errors))
|
||||||
|
return AssemblyItems();
|
||||||
}
|
}
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
|
@ -45,9 +45,10 @@ public:
|
|||||||
m_reader.parse(generatedInterfaceString, generatedInterface);
|
m_reader.parse(generatedInterfaceString, generatedInterface);
|
||||||
Json::Value expectedInterface;
|
Json::Value expectedInterface;
|
||||||
m_reader.parse(_expectedInterfaceString, expectedInterface);
|
m_reader.parse(_expectedInterfaceString, expectedInterface);
|
||||||
BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface,
|
BOOST_CHECK_MESSAGE(
|
||||||
"Expected:\n" << expectedInterface.toStyledString() <<
|
expectedInterface == generatedInterface,
|
||||||
"\n but got:\n" << generatedInterface.toStyledString());
|
"Expected:\n" << expectedInterface.toStyledString() << "\n but got:\n" << generatedInterface.toStyledString()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -4705,7 +4705,7 @@ BOOST_AUTO_TEST_CASE(dev_title_at_function_error)
|
|||||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
compileRequireThrow<DocstringParsingError>(sourceCode);
|
compileRequireError(sourceCode, Error::Type::DocstringParsingError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
|
BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
|
||||||
@ -4717,7 +4717,7 @@ BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
|
|||||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
compileRequireThrow<DocstringParsingError>(sourceCode);
|
compileRequireError(sourceCode, Error::Type::DocstringParsingError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,11 +92,13 @@ bytes compileFirstExpression(
|
|||||||
vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {}
|
vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {}
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Parser parser;
|
|
||||||
ASTPointer<SourceUnit> sourceUnit;
|
ASTPointer<SourceUnit> sourceUnit;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)));
|
ErrorList errors;
|
||||||
|
sourceUnit = Parser(errors).parse(make_shared<Scanner>(CharStream(_sourceCode)));
|
||||||
|
if (!sourceUnit)
|
||||||
|
return bytes();
|
||||||
}
|
}
|
||||||
catch(boost::exception const& _e)
|
catch(boost::exception const& _e)
|
||||||
{
|
{
|
||||||
@ -108,9 +110,9 @@ bytes compileFirstExpression(
|
|||||||
declarations.reserve(_globalDeclarations.size() + 1);
|
declarations.reserve(_globalDeclarations.size() + 1);
|
||||||
for (ASTPointer<Declaration const> const& variable: _globalDeclarations)
|
for (ASTPointer<Declaration const> const& variable: _globalDeclarations)
|
||||||
declarations.push_back(variable.get());
|
declarations.push_back(variable.get());
|
||||||
/// TODO:
|
|
||||||
ErrorList errorList;
|
ErrorList errors;
|
||||||
NameAndTypeResolver resolver(declarations, errorList);
|
NameAndTypeResolver resolver(declarations, errors);
|
||||||
resolver.registerDeclarations(*sourceUnit);
|
resolver.registerDeclarations(*sourceUnit);
|
||||||
|
|
||||||
vector<ContractDefinition const*> inheritanceHierarchy;
|
vector<ContractDefinition const*> inheritanceHierarchy;
|
||||||
@ -123,7 +125,7 @@ bytes compileFirstExpression(
|
|||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||||
{
|
{
|
||||||
TypeChecker typeChecker;
|
TypeChecker typeChecker(errors);
|
||||||
BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract));
|
BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract));
|
||||||
}
|
}
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
|
@ -44,16 +44,23 @@ namespace test
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
pair<ASTPointer<SourceUnit>, shared_ptr<Exception const>>
|
pair<ASTPointer<SourceUnit>, std::shared_ptr<Error::Type const>>
|
||||||
parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false)
|
parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false)
|
||||||
{
|
{
|
||||||
Parser parser;
|
ErrorList errors;
|
||||||
|
Parser parser(errors);
|
||||||
ASTPointer<SourceUnit> sourceUnit;
|
ASTPointer<SourceUnit> sourceUnit;
|
||||||
shared_ptr<Exception const> err;
|
|
||||||
// catch exceptions for a transition period
|
// catch exceptions for a transition period
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
|
sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
|
||||||
|
if(!sourceUnit)
|
||||||
|
return make_pair(sourceUnit, nullptr);
|
||||||
|
|
||||||
|
NameAndTypeResolver resolver({}, errors);
|
||||||
|
solAssert(Error::containsOnlyWarnings(errors), "");
|
||||||
|
resolver.registerDeclarations(*sourceUnit);
|
||||||
|
|
||||||
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
|
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
|
||||||
NameAndTypeResolver resolver(globalContext->declarations());
|
NameAndTypeResolver resolver(globalContext->declarations());
|
||||||
resolver.registerDeclarations(*sourceUnit);
|
resolver.registerDeclarations(*sourceUnit);
|
||||||
@ -71,51 +78,45 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false)
|
|||||||
{
|
{
|
||||||
globalContext->setCurrentContract(*contract);
|
globalContext->setCurrentContract(*contract);
|
||||||
resolver.updateDeclaration(*globalContext->currentThis());
|
resolver.updateDeclaration(*globalContext->currentThis());
|
||||||
TypeChecker typeChecker;
|
|
||||||
|
TypeChecker typeChecker(errors);
|
||||||
bool success = typeChecker.checkTypeRequirements(*contract);
|
bool success = typeChecker.checkTypeRequirements(*contract);
|
||||||
BOOST_CHECK(success || !typeChecker.errors().empty());
|
BOOST_CHECK(success || !typeChecker.errors().empty());
|
||||||
for (auto const& firstError: typeChecker.errors())
|
|
||||||
|
for (auto const& currentError: errors)
|
||||||
{
|
{
|
||||||
if (_reportWarnings || !dynamic_pointer_cast<Warning const>(firstError))
|
if (
|
||||||
{
|
(_reportWarnings && currentError->type() == Error::Type::Warning) ||
|
||||||
err = firstError;
|
(!_reportWarnings && currentError->type() != Error::Type::Warning)
|
||||||
break;
|
)
|
||||||
}
|
return make_pair(sourceUnit, std::make_shared<Error::Type const>(currentError->type()));
|
||||||
else if (_reportWarnings)
|
|
||||||
{
|
|
||||||
err = firstError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ParserError const& _exception)
|
catch(Error const& _e)
|
||||||
{
|
{
|
||||||
return make_pair(sourceUnit, make_shared<ParserError>(_exception));
|
return make_pair(sourceUnit, std::make_shared<Error::Type const>(_e.type()));
|
||||||
}
|
}
|
||||||
catch (DeclarationError const& _exception)
|
catch (Exception const& _exception)
|
||||||
{
|
{
|
||||||
return make_pair(sourceUnit, make_shared<DeclarationError>(_exception));
|
return make_pair(sourceUnit, nullptr);
|
||||||
}
|
}
|
||||||
catch (TypeError const& _exception)
|
return make_pair(sourceUnit, nullptr);
|
||||||
{
|
|
||||||
return make_pair(sourceUnit, make_shared<TypeError>(_exception));
|
|
||||||
}
|
|
||||||
return make_pair(sourceUnit, err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTPointer<SourceUnit> parseAndAnalyse(string const& _source)
|
ASTPointer<SourceUnit> parseAndAnalyse(string const& _source)
|
||||||
{
|
{
|
||||||
auto sourceAndError = parseAnalyseAndReturnError(_source);
|
auto sourceAndError = parseAnalyseAndReturnError(_source);
|
||||||
BOOST_REQUIRE(!sourceAndError.second);
|
BOOST_REQUIRE(!!sourceAndError.first);
|
||||||
return sourceAndError.first;
|
return sourceAndError.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Exception const> parseAndAnalyseReturnError(std::string const& _source, bool _warning = false)
|
Error::Type parseAndAnalyseReturnErrorType(std::string const& _source, bool _warning = false)
|
||||||
{
|
{
|
||||||
auto sourceAndError = parseAnalyseAndReturnError(_source, _warning);
|
auto sourceAndError = parseAnalyseAndReturnError(_source, _warning);
|
||||||
BOOST_REQUIRE(!!sourceAndError.second);
|
BOOST_REQUIRE(!!sourceAndError.second);
|
||||||
return sourceAndError.second;
|
BOOST_REQUIRE(!!sourceAndError.first);
|
||||||
|
return *sourceAndError.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source, unsigned index)
|
static ContractDefinition const* retrieveContract(ASTPointer<SourceUnit> _source, unsigned index)
|
||||||
@ -140,10 +141,6 @@ static FunctionTypePointer const& retrieveFunctionBySignature(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOLIDITY_CHECK_ERROR_TYPE(_statement, _ErrorType) \
|
|
||||||
BOOST_CHECK(!!dynamic_cast<_ErrorType const*>(_statement.get()))
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)
|
BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution)
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(smoke_test)
|
BOOST_AUTO_TEST_CASE(smoke_test)
|
||||||
@ -161,7 +158,7 @@ BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
|
|||||||
" uint256 variable;\n"
|
" uint256 variable;\n"
|
||||||
" uint128 variable;\n"
|
" uint128 variable;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(double_function_declaration)
|
BOOST_AUTO_TEST_CASE(double_function_declaration)
|
||||||
@ -170,7 +167,7 @@ BOOST_AUTO_TEST_CASE(double_function_declaration)
|
|||||||
" function fun() { uint x; }\n"
|
" function fun() { uint x; }\n"
|
||||||
" function fun() { uint x; }\n"
|
" function fun() { uint x; }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(double_variable_declaration)
|
BOOST_AUTO_TEST_CASE(double_variable_declaration)
|
||||||
@ -178,7 +175,7 @@ BOOST_AUTO_TEST_CASE(double_variable_declaration)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" function f() { uint256 x; if (true) { uint256 x; } }\n"
|
" function f() { uint256 x; if (true) { uint256 x; } }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(name_shadowing)
|
BOOST_AUTO_TEST_CASE(name_shadowing)
|
||||||
@ -205,7 +202,7 @@ BOOST_AUTO_TEST_CASE(undeclared_name)
|
|||||||
" uint256 variable;\n"
|
" uint256 variable;\n"
|
||||||
" function f(uint256 arg) { f(notfound); }"
|
" function f(uint256 arg) { f(notfound); }"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
|
BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
|
||||||
@ -225,7 +222,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
|
|||||||
" MyStructName x;\n"
|
" MyStructName x;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
|
BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
|
||||||
@ -240,7 +237,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
|
|||||||
" MyStructName1 x;\n"
|
" MyStructName1 x;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
|
BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
|
||||||
@ -287,7 +284,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" function f() returns (bool r1, bool r2) { return 1 >= 2; }"
|
" function f() returns (bool r1, bool r2) { return 1 >= 2; }"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
|
BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
|
||||||
@ -295,7 +292,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return_wrong_type)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" function f() returns (uint256 r) { return 1 >= 2; }"
|
" function f() returns (uint256 r) { return 1 >= 2; }"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(type_checking_function_call)
|
BOOST_AUTO_TEST_CASE(type_checking_function_call)
|
||||||
@ -320,7 +317,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_for_comparison_invalid)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" function f() { int32(2) == uint64(2); }"
|
" function f() { int32(2) == uint64(2); }"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
|
BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion)
|
||||||
@ -356,7 +353,7 @@ BOOST_AUTO_TEST_CASE(balance_invalid)
|
|||||||
" address(0).balance = 7;\n"
|
" address(0).balance = 7;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_to_mapping)
|
BOOST_AUTO_TEST_CASE(assignment_to_mapping)
|
||||||
@ -371,7 +368,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_mapping)
|
|||||||
" data.map = a;\n"
|
" data.map = a;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_to_struct)
|
BOOST_AUTO_TEST_CASE(assignment_to_struct)
|
||||||
@ -395,7 +392,7 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor)
|
|||||||
" function test() returns (uint a) {\n"
|
" function test() returns (uint a) {\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(forward_function_reference)
|
BOOST_AUTO_TEST_CASE(forward_function_reference)
|
||||||
@ -483,7 +480,7 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract)
|
|||||||
function foo() { b = new base();}
|
function foo() { b = new base();}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
|
BOOST_AUTO_TEST_CASE(abstract_contract_constructor_args_optional)
|
||||||
@ -527,7 +524,7 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract)
|
|||||||
contract derived is base { function foo() {} }
|
contract derived is base { function foo() {} }
|
||||||
contract wrong is derived { function foo(); }
|
contract wrong is derived { function foo(); }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_canonical_signature)
|
BOOST_AUTO_TEST_CASE(function_canonical_signature)
|
||||||
@ -636,7 +633,7 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion)
|
|||||||
}
|
}
|
||||||
function g (C c) external {}
|
function g (C c) external {}
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
|
BOOST_AUTO_TEST_CASE(function_internal_allowed_conversion)
|
||||||
@ -668,7 +665,7 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion)
|
|||||||
g(a);
|
g(a);
|
||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
|
BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
|
||||||
@ -679,7 +676,7 @@ BOOST_AUTO_TEST_CASE(hash_collision_in_interface)
|
|||||||
" function tgeo() {\n"
|
" function tgeo() {\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(inheritance_basic)
|
BOOST_AUTO_TEST_CASE(inheritance_basic)
|
||||||
@ -713,7 +710,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance)
|
|||||||
contract A is B { }
|
contract A is B { }
|
||||||
contract B is A { }
|
contract B is A { }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(legal_override_direct)
|
BOOST_AUTO_TEST_CASE(legal_override_direct)
|
||||||
@ -741,7 +738,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_visibility)
|
|||||||
contract B { function f() internal {} }
|
contract B { function f() internal {} }
|
||||||
contract C is B { function f() public {} }
|
contract C is B { function f() public {} }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(illegal_override_constness)
|
BOOST_AUTO_TEST_CASE(illegal_override_constness)
|
||||||
@ -750,7 +747,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_constness)
|
|||||||
contract B { function f() constant {} }
|
contract B { function f() constant {} }
|
||||||
contract C is B { function f() {} }
|
contract C is B { function f() {} }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(complex_inheritance)
|
BOOST_AUTO_TEST_CASE(complex_inheritance)
|
||||||
@ -820,7 +817,7 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion)
|
|||||||
function f() { B b = A(1); }
|
function f() { B b = A(1); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_modifier_invocation)
|
BOOST_AUTO_TEST_CASE(function_modifier_invocation)
|
||||||
@ -843,7 +840,7 @@ BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
|
|||||||
modifier mod1(uint a) { if (a > 0) _ }
|
modifier mod1(uint a) { if (a > 0) _ }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
|
BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
|
||||||
@ -884,7 +881,7 @@ BOOST_AUTO_TEST_CASE(illegal_modifier_override)
|
|||||||
contract A { modifier mod(uint a) {} }
|
contract A { modifier mod(uint a) {} }
|
||||||
contract B is A { modifier mod(uint8 a) {} }
|
contract B is A { modifier mod(uint8 a) {} }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifier_overrides_function)
|
BOOST_AUTO_TEST_CASE(modifier_overrides_function)
|
||||||
@ -893,7 +890,7 @@ BOOST_AUTO_TEST_CASE(modifier_overrides_function)
|
|||||||
contract A { modifier mod(uint a) {} }
|
contract A { modifier mod(uint a) {} }
|
||||||
contract B is A { function mod(uint a) {} }
|
contract B is A { function mod(uint a) {} }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
|
BOOST_AUTO_TEST_CASE(function_overrides_modifier)
|
||||||
@ -902,7 +899,7 @@ BOOST_AUTO_TEST_CASE(function_overrides_modifier)
|
|||||||
contract A { function mod(uint a) {} }
|
contract A { function mod(uint a) {} }
|
||||||
contract B is A { modifier mod(uint a) {} }
|
contract B is A { modifier mod(uint a) {} }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifier_returns_value)
|
BOOST_AUTO_TEST_CASE(modifier_returns_value)
|
||||||
@ -913,7 +910,7 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value)
|
|||||||
modifier mod(uint a) { return 7; }
|
modifier mod(uint a) { return 7; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(state_variable_accessors)
|
BOOST_AUTO_TEST_CASE(state_variable_accessors)
|
||||||
@ -964,7 +961,7 @@ BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor)
|
|||||||
"uint256 foo;\n"
|
"uint256 foo;\n"
|
||||||
" function foo() {}\n"
|
" function foo() {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(private_state_variable)
|
BOOST_AUTO_TEST_CASE(private_state_variable)
|
||||||
@ -1022,7 +1019,7 @@ BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class1)
|
|||||||
"contract Child is Parent2{\n"
|
"contract Child is Parent2{\n"
|
||||||
" function foo() returns (uint256) { return Parent2.m_aMember1; }\n"
|
" function foo() returns (uint256) { return Parent2.m_aMember1; }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
|
BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
|
||||||
@ -1037,7 +1034,7 @@ BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2)
|
|||||||
" function foo() returns (uint256) { return Child.m_aMember2; }\n"
|
" function foo() returns (uint256) { return Child.m_aMember2; }\n"
|
||||||
" uint256 public m_aMember3;\n"
|
" uint256 public m_aMember3;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fallback_function)
|
BOOST_AUTO_TEST_CASE(fallback_function)
|
||||||
@ -1059,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments)
|
|||||||
function(uint a) { x = 2; }
|
function(uint a) { x = 2; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fallback_function_twice)
|
BOOST_AUTO_TEST_CASE(fallback_function_twice)
|
||||||
@ -1071,7 +1068,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice)
|
|||||||
function() { x = 3; }
|
function() { x = 3; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
|
BOOST_AUTO_TEST_CASE(fallback_function_inheritance)
|
||||||
@ -1104,7 +1101,7 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed)
|
|||||||
contract c {
|
contract c {
|
||||||
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);
|
event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d);
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed)
|
BOOST_AUTO_TEST_CASE(anonymous_event_four_indexed)
|
||||||
@ -1178,7 +1175,7 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function)
|
|||||||
contract d {
|
contract d {
|
||||||
function g() { c(0).f(); }
|
function g() { c(0).f(); }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
|
BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
|
||||||
@ -1190,7 +1187,7 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility)
|
|||||||
contract d {
|
contract d {
|
||||||
function g() { c(0).a(); }
|
function g() { c(0).a(); }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
|
BOOST_AUTO_TEST_CASE(access_to_internal_state_variable)
|
||||||
@ -1211,7 +1208,7 @@ BOOST_AUTO_TEST_CASE(error_count_in_named_args)
|
|||||||
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
||||||
" function b() returns (uint r) { r = a({a: 1}); }\n"
|
" function b() returns (uint r) { r = a({a: 1}); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_in_named_args)
|
BOOST_AUTO_TEST_CASE(empty_in_named_args)
|
||||||
@ -1220,7 +1217,7 @@ BOOST_AUTO_TEST_CASE(empty_in_named_args)
|
|||||||
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
||||||
" function b() returns (uint r) { r = a({}); }\n"
|
" function b() returns (uint r) { r = a({}); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
|
BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
|
||||||
@ -1229,7 +1226,7 @@ BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args)
|
|||||||
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
||||||
" function b() returns (uint r) { r = a({a: 1, a: 2}); }\n"
|
" function b() returns (uint r) { r = a({a: 1, a: 2}); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
|
BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
|
||||||
@ -1238,7 +1235,7 @@ BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args)
|
|||||||
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
" function a(uint a, uint b) returns (uint r) { r = a + b; }\n"
|
||||||
" function b() returns (uint r) { r = a({a: 1, c: 2}); }\n"
|
" function b() returns (uint r) { r = a({a: 1, c: 2}); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
|
BOOST_AUTO_TEST_CASE(empty_name_input_parameter)
|
||||||
@ -1280,13 +1277,18 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter_with_named_one)
|
|||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
|
BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type)
|
||||||
{
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
char const* sourceCode = "contract c { function f() { var (x) = f(); } }";
|
char const* sourceCode = "contract c { function f() { var (x) = f(); } }";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
||||||
|
=======
|
||||||
|
char const* sourceCode = "contract c { function f() { var x = f(); } }";
|
||||||
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
|
>>>>>>> 2cd6509... errors instead of exceptions
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
|
BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
|
||||||
@ -1309,7 +1311,7 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
|
|||||||
}
|
}
|
||||||
uint256 a;
|
uint256 a;
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent)
|
BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent)
|
||||||
@ -1318,7 +1320,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent)
|
|||||||
contract test {
|
contract test {
|
||||||
function f() returns(uint d) { return 2 ** -3; }
|
function f() returns(uint d) { return 2 ** -3; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
|
BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
|
||||||
@ -1327,7 +1329,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
|
|||||||
contract test {
|
contract test {
|
||||||
function f() returns(uint d) { return 2 ** 10000000000; }
|
function f() returns(uint d) { return 2 ** 10000000000; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(enum_member_access)
|
BOOST_AUTO_TEST_CASE(enum_member_access)
|
||||||
@ -1357,7 +1359,7 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access)
|
|||||||
ActionChoices choices;
|
ActionChoices choices;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
|
BOOST_AUTO_TEST_CASE(enum_explicit_conversion_is_okay)
|
||||||
@ -1408,7 +1410,7 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay)
|
|||||||
uint64 b;
|
uint64 b;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(enum_duplicate_values)
|
BOOST_AUTO_TEST_CASE(enum_duplicate_values)
|
||||||
@ -1418,7 +1420,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values)
|
|||||||
enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }
|
enum ActionChoices { GoLeft, GoRight, GoLeft, Sit }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(private_visibility)
|
BOOST_AUTO_TEST_CASE(private_visibility)
|
||||||
@ -1431,7 +1433,7 @@ BOOST_AUTO_TEST_CASE(private_visibility)
|
|||||||
function g() { f(); }
|
function g() { f(); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
|
BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
|
||||||
@ -1444,7 +1446,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access)
|
|||||||
function g() { base.f(); }
|
function g() { base.f(); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_visibility)
|
BOOST_AUTO_TEST_CASE(external_visibility)
|
||||||
@ -1455,7 +1457,7 @@ BOOST_AUTO_TEST_CASE(external_visibility)
|
|||||||
function g() { f(); }
|
function g() { f(); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_base_visibility)
|
BOOST_AUTO_TEST_CASE(external_base_visibility)
|
||||||
@ -1468,7 +1470,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility)
|
|||||||
function g() { base.f(); }
|
function g() { base.f(); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_argument_assign)
|
BOOST_AUTO_TEST_CASE(external_argument_assign)
|
||||||
@ -1478,7 +1480,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign)
|
|||||||
function f(uint a) external { a = 1; }
|
function f(uint a) external { a = 1; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_argument_increment)
|
BOOST_AUTO_TEST_CASE(external_argument_increment)
|
||||||
@ -1488,7 +1490,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment)
|
|||||||
function f(uint a) external { a++; }
|
function f(uint a) external { a++; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_argument_delete)
|
BOOST_AUTO_TEST_CASE(external_argument_delete)
|
||||||
@ -1498,7 +1500,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete)
|
|||||||
function f(uint a) external { delete a; }
|
function f(uint a) external { delete a; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
|
BOOST_AUTO_TEST_CASE(test_for_bug_override_function_with_bytearray_type)
|
||||||
@ -1520,7 +1522,7 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length)
|
|||||||
contract c {
|
contract c {
|
||||||
function f(uint a) { uint8[a] x; }
|
function f(uint a) { uint8[a] x; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
|
BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
|
||||||
@ -1531,7 +1533,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1)
|
|||||||
uint[] b;
|
uint[] b;
|
||||||
function f() { b = a; }
|
function f() { b = a; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
|
BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
|
||||||
@ -1542,7 +1544,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2)
|
|||||||
uint8[] b;
|
uint8[] b;
|
||||||
function f() { b = a; }
|
function f() { b = a; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
|
BOOST_AUTO_TEST_CASE(array_copy_with_different_types_conversion_possible)
|
||||||
@ -1575,7 +1577,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static)
|
|||||||
uint[80] b;
|
uint[80] b;
|
||||||
function f() { b = a; }
|
function f() { b = a; }
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
|
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
|
||||||
@ -1584,7 +1586,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int)
|
|||||||
contract c {
|
contract c {
|
||||||
uint8 a = 1000;
|
uint8 a = 1000;
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
|
BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
|
||||||
@ -1593,7 +1595,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string)
|
|||||||
contract c {
|
contract c {
|
||||||
uint a = "abc";
|
uint a = "abc";
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
|
BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
|
||||||
@ -1718,7 +1720,7 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable)
|
|||||||
function changeIt() { x = 9; }
|
function changeIt() { x = 9; }
|
||||||
uint constant x = 56;
|
uint constant x = 56;
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(complex_const_variable)
|
BOOST_AUTO_TEST_CASE(complex_const_variable)
|
||||||
@ -1728,7 +1730,7 @@ BOOST_AUTO_TEST_CASE(complex_const_variable)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
mapping(uint => bool) constant mapVar;
|
mapping(uint => bool) constant mapVar;
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
|
BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
|
||||||
@ -1737,20 +1739,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
uint constant y;
|
uint constant y;
|
||||||
})";
|
})";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(local_const_variable)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract Foo {
|
|
||||||
function localConst() returns (uint ret)
|
|
||||||
{
|
|
||||||
uint constant local = 4;
|
|
||||||
return local;
|
|
||||||
}
|
|
||||||
})";
|
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), ParserError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
|
BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
|
||||||
@ -1762,7 +1751,7 @@ BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve)
|
|||||||
function g() returns(uint) { return f(3, 5); }
|
function g() returns(uint) { return f(3, 5); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
|
BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
|
||||||
@ -1775,7 +1764,7 @@ BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function)
|
|||||||
function g() returns(uint) { return f(1); }
|
function g() returns(uint) { return f(1); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function)
|
BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function)
|
||||||
@ -1798,7 +1787,7 @@ BOOST_AUTO_TEST_CASE(assignment_of_overloaded_function)
|
|||||||
function g() returns(uint) { var x = f; return x(7); }
|
function g() returns(uint) { var x = f; return x(7); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_types_clash)
|
BOOST_AUTO_TEST_CASE(external_types_clash)
|
||||||
@ -1812,7 +1801,7 @@ BOOST_AUTO_TEST_CASE(external_types_clash)
|
|||||||
function f(uint8 a) { }
|
function f(uint8 a) { }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(override_changes_return_types)
|
BOOST_AUTO_TEST_CASE(override_changes_return_types)
|
||||||
@ -1825,7 +1814,7 @@ BOOST_AUTO_TEST_CASE(override_changes_return_types)
|
|||||||
function f(uint a) returns (uint8) { }
|
function f(uint a) returns (uint8) { }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multiple_constructors)
|
BOOST_AUTO_TEST_CASE(multiple_constructors)
|
||||||
@ -1836,7 +1825,7 @@ BOOST_AUTO_TEST_CASE(multiple_constructors)
|
|||||||
function test() {}
|
function test() {}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(equal_overload)
|
BOOST_AUTO_TEST_CASE(equal_overload)
|
||||||
@ -1847,7 +1836,7 @@ BOOST_AUTO_TEST_CASE(equal_overload)
|
|||||||
function test(uint a) external {}
|
function test(uint a) external {}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(uninitialized_var)
|
BOOST_AUTO_TEST_CASE(uninitialized_var)
|
||||||
@ -1857,7 +1846,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_var)
|
|||||||
function f() returns (uint) { var x; return 2; }
|
function f() returns (uint) { var x; return 2; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(string)
|
BOOST_AUTO_TEST_CASE(string)
|
||||||
@ -1879,7 +1868,7 @@ BOOST_AUTO_TEST_CASE(string_index)
|
|||||||
function f() { var a = s[2]; }
|
function f() { var a = s[2]; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(string_length)
|
BOOST_AUTO_TEST_CASE(string_length)
|
||||||
@ -1890,7 +1879,7 @@ BOOST_AUTO_TEST_CASE(string_length)
|
|||||||
function f() { var a = s.length; }
|
function f() { var a = s.length; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
|
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
|
||||||
@ -1900,7 +1889,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound)
|
|||||||
int8 public i = -129;
|
int8 public i = -129;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_min)
|
BOOST_AUTO_TEST_CASE(negative_integers_to_signed_min)
|
||||||
@ -1920,7 +1909,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound)
|
|||||||
int8 public j = 128;
|
int8 public j = 128;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max)
|
BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound_max)
|
||||||
@ -1940,7 +1929,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned)
|
|||||||
uint8 public x = -1;
|
uint8 public x = -1;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
|
BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
|
||||||
@ -1950,7 +1939,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
|
|||||||
uint8 public x = 700;
|
uint8 public x = 700;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(integer_boolean_operators)
|
BOOST_AUTO_TEST_CASE(integer_boolean_operators)
|
||||||
@ -1958,15 +1947,15 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators)
|
|||||||
char const* sourceCode1 = R"(
|
char const* sourceCode1 = R"(
|
||||||
contract test { function() { uint x = 1; uint y = 2; x || y; } }
|
contract test { function() { uint x = 1; uint y = 2; x || y; } }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode1), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode1) == Error::Type::TypeError);
|
||||||
char const* sourceCode2 = R"(
|
char const* sourceCode2 = R"(
|
||||||
contract test { function() { uint x = 1; uint y = 2; x && y; } }
|
contract test { function() { uint x = 1; uint y = 2; x && y; } }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode2), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode2) == Error::Type::TypeError);
|
||||||
char const* sourceCode3 = R"(
|
char const* sourceCode3 = R"(
|
||||||
contract test { function() { uint x = 1; !x; } }
|
contract test { function() { uint x = 1; !x; } }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode3), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode3) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(reference_compare_operators)
|
BOOST_AUTO_TEST_CASE(reference_compare_operators)
|
||||||
@ -1974,11 +1963,11 @@ BOOST_AUTO_TEST_CASE(reference_compare_operators)
|
|||||||
char const* sourceCode1 = R"(
|
char const* sourceCode1 = R"(
|
||||||
contract test { bytes a; bytes b; function() { a == b; } }
|
contract test { bytes a; bytes b; function() { a == b; } }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode1), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode1) == Error::Type::TypeError);
|
||||||
char const* sourceCode2 = R"(
|
char const* sourceCode2 = R"(
|
||||||
contract test { struct s {uint a;} s x; s y; function() { x == y; } }
|
contract test { struct s {uint a;} s x; s y; function() { x == y; } }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode2), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode2) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
|
BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
|
||||||
@ -1988,7 +1977,7 @@ BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
|
|||||||
function f(uint[] memory a) external {}
|
function f(uint[] memory a) external {}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
|
BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
|
||||||
@ -1998,7 +1987,7 @@ BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
|
|||||||
function f(uint[] storage a) external {}
|
function f(uint[] storage a) external {}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_location_local_variables)
|
BOOST_AUTO_TEST_CASE(storage_location_local_variables)
|
||||||
@ -2024,7 +2013,7 @@ BOOST_AUTO_TEST_CASE(no_mappings_in_memory_array)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
|
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
|
||||||
@ -2038,7 +2027,7 @@ BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
|
BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
|
||||||
@ -2055,7 +2044,7 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
|
BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
|
||||||
@ -2069,7 +2058,7 @@ BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
|
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
|
||||||
@ -2096,7 +2085,7 @@ BOOST_AUTO_TEST_CASE(function_argument_mem_to_storage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_argument_storage_to_mem)
|
BOOST_AUTO_TEST_CASE(function_argument_storage_to_mem)
|
||||||
@ -2125,7 +2114,7 @@ BOOST_AUTO_TEST_CASE(mem_array_assignment_changes_base_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
|
BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
|
||||||
@ -2138,7 +2127,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
|
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
|
||||||
@ -2151,7 +2140,7 @@ BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(struct_constructor)
|
BOOST_AUTO_TEST_CASE(struct_constructor)
|
||||||
@ -2217,7 +2206,7 @@ BOOST_AUTO_TEST_CASE(invalid_integer_literal_fraction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
|
BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
|
||||||
@ -2229,7 +2218,7 @@ BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
||||||
@ -2244,7 +2233,7 @@ BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(string_bytes_conversion)
|
BOOST_AUTO_TEST_CASE(string_bytes_conversion)
|
||||||
@ -2270,7 +2259,7 @@ BOOST_AUTO_TEST_CASE(inheriting_from_library)
|
|||||||
library Lib {}
|
library Lib {}
|
||||||
contract Test is Lib {}
|
contract Test is Lib {}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(inheriting_library)
|
BOOST_AUTO_TEST_CASE(inheriting_library)
|
||||||
@ -2279,7 +2268,7 @@ BOOST_AUTO_TEST_CASE(inheriting_library)
|
|||||||
contract Test {}
|
contract Test {}
|
||||||
library Lib is Test {}
|
library Lib is Test {}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(library_having_variables)
|
BOOST_AUTO_TEST_CASE(library_having_variables)
|
||||||
@ -2287,7 +2276,7 @@ BOOST_AUTO_TEST_CASE(library_having_variables)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
library Lib { uint x; }
|
library Lib { uint x; }
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_library)
|
BOOST_AUTO_TEST_CASE(valid_library)
|
||||||
@ -2321,7 +2310,7 @@ BOOST_AUTO_TEST_CASE(creating_contract_within_the_contract)
|
|||||||
function f() { var x = new Test(); }
|
function f() { var x = new Test(); }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
|
BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
|
||||||
@ -2335,7 +2324,7 @@ BOOST_AUTO_TEST_CASE(array_out_of_bound_access)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
|
BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
|
||||||
@ -2345,7 +2334,7 @@ BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer)
|
|||||||
function f() { string x = "abc"; }
|
function f() { string x = "abc"; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError);
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(non_initialized_references)
|
BOOST_AUTO_TEST_CASE(non_initialized_references)
|
||||||
@ -2363,7 +2352,10 @@ BOOST_AUTO_TEST_CASE(non_initialized_references)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text, true), Warning);
|
|
||||||
|
auto b = parseAndAnalyseReturnErrorType(text, true);
|
||||||
|
(void)b;
|
||||||
|
BOOST_CHECK(parseAndAnalyseReturnErrorType(text, true) == Error::Type::Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(sha3_with_large_integer_constant)
|
BOOST_AUTO_TEST_CASE(sha3_with_large_integer_constant)
|
||||||
|
@ -39,10 +39,11 @@ namespace test
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
ASTPointer<ContractDefinition> parseText(std::string const& _source)
|
ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors)
|
||||||
{
|
{
|
||||||
Parser parser;
|
ASTPointer<SourceUnit> sourceUnit = Parser(_errors).parse(std::make_shared<Scanner>(CharStream(_source)));
|
||||||
ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
|
if(!sourceUnit)
|
||||||
|
return ASTPointer<ContractDefinition>();
|
||||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||||
if (ASTPointer<ContractDefinition> contract = dynamic_pointer_cast<ContractDefinition>(node))
|
if (ASTPointer<ContractDefinition> contract = dynamic_pointer_cast<ContractDefinition>(node))
|
||||||
return contract;
|
return contract;
|
||||||
@ -50,8 +51,30 @@ ASTPointer<ContractDefinition> parseText(std::string const& _source)
|
|||||||
return ASTPointer<ContractDefinition>();
|
return ASTPointer<ContractDefinition>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkFunctionNatspec(ASTPointer<FunctionDefinition> _function,
|
bool successParse(std::string const& _source)
|
||||||
std::string const& _expectedDoc)
|
{
|
||||||
|
ErrorList errors;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auto sourceUnit = parseText(_source, errors);
|
||||||
|
if(!sourceUnit)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (fatalError const& _exception)
|
||||||
|
{
|
||||||
|
if (Error::containsErrorOfType(errors, Error::Type::ParserError))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Error::containsErrorOfType(errors, Error::Type::ParserError))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkFunctionNatspec(
|
||||||
|
ASTPointer<FunctionDefinition> _function,
|
||||||
|
std::string const& _expectedDoc
|
||||||
|
)
|
||||||
{
|
{
|
||||||
auto doc = _function->documentation();
|
auto doc = _function->documentation();
|
||||||
BOOST_CHECK_MESSAGE(doc != nullptr, "Function does not have Natspec Doc as expected");
|
BOOST_CHECK_MESSAGE(doc != nullptr, "Function does not have Natspec Doc as expected");
|
||||||
@ -68,7 +91,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" uint256 stateVariable1;\n"
|
" uint256 stateVariable1;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration)
|
BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration)
|
||||||
@ -76,7 +99,7 @@ BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" uint256 ;\n"
|
" uint256 ;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
BOOST_CHECK_THROW(parseText(text), Error);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_function)
|
BOOST_AUTO_TEST_CASE(empty_function)
|
||||||
@ -87,7 +110,7 @@ BOOST_AUTO_TEST_CASE(empty_function)
|
|||||||
" returns (int id)\n"
|
" returns (int id)\n"
|
||||||
" { }\n"
|
" { }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(no_function_params)
|
BOOST_AUTO_TEST_CASE(no_function_params)
|
||||||
@ -96,7 +119,7 @@ BOOST_AUTO_TEST_CASE(no_function_params)
|
|||||||
" uint256 stateVar;\n"
|
" uint256 stateVar;\n"
|
||||||
" function functionName() {}\n"
|
" function functionName() {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(single_function_param)
|
BOOST_AUTO_TEST_CASE(single_function_param)
|
||||||
@ -105,7 +128,7 @@ BOOST_AUTO_TEST_CASE(single_function_param)
|
|||||||
" uint256 stateVar;\n"
|
" uint256 stateVar;\n"
|
||||||
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_no_body)
|
BOOST_AUTO_TEST_CASE(function_no_body)
|
||||||
@ -113,7 +136,7 @@ BOOST_AUTO_TEST_CASE(function_no_body)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" function functionName(bytes32 input) returns (bytes32 out);\n"
|
" function functionName(bytes32 input) returns (bytes32 out);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed.");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args)
|
BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args)
|
||||||
@ -122,7 +145,7 @@ BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args)
|
|||||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||||
" function b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n"
|
" function b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
|
BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
|
||||||
@ -131,7 +154,7 @@ BOOST_AUTO_TEST_CASE(missing_argument_in_named_args)
|
|||||||
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
" function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n"
|
||||||
" function b() returns (uint r) { r = a({a: , b: , c: }); }\n"
|
" function b() returns (uint r) { r = a({a: , b: , c: }); }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(two_exact_functions)
|
BOOST_AUTO_TEST_CASE(two_exact_functions)
|
||||||
@ -145,7 +168,8 @@ BOOST_AUTO_TEST_CASE(two_exact_functions)
|
|||||||
// with support of overloaded functions, during parsing,
|
// with support of overloaded functions, during parsing,
|
||||||
// we can't determine whether they match exactly, however
|
// we can't determine whether they match exactly, however
|
||||||
// it will throw DeclarationError in following stage.
|
// it will throw DeclarationError in following stage.
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
// TODO add test to the SolidityNameAndTypeDeclaration
|
||||||
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(overloaded_functions)
|
BOOST_AUTO_TEST_CASE(overloaded_functions)
|
||||||
@ -156,20 +180,23 @@ BOOST_AUTO_TEST_CASE(overloaded_functions)
|
|||||||
function fun(uint a, uint b) returns(uint r) { return a + b; }
|
function fun(uint a, uint b) returns(uint r) { return a + b; }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
|
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
|
||||||
{
|
{
|
||||||
ASTPointer<ContractDefinition> contract;
|
|
||||||
ASTPointer<FunctionDefinition> function;
|
|
||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" uint256 stateVar;\n"
|
" uint256 stateVar;\n"
|
||||||
" /// This is a test function\n"
|
" /// This is a test function\n"
|
||||||
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList e;
|
||||||
|
ASTPointer<ContractDefinition> contract = parseText(text, e);
|
||||||
|
ASTPointer<FunctionDefinition> function;
|
||||||
|
|
||||||
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
checkFunctionNatspec(function, "This is a test function");
|
checkFunctionNatspec(function, "This is a test function");
|
||||||
}
|
}
|
||||||
@ -183,8 +210,9 @@ BOOST_AUTO_TEST_CASE(function_normal_comments)
|
|||||||
" // We won't see this comment\n"
|
" // We won't see this comment\n"
|
||||||
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
" function functionName(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
BOOST_CHECK_MESSAGE(function->documentation() == nullptr,
|
BOOST_CHECK_MESSAGE(function->documentation() == nullptr,
|
||||||
"Should not have gotten a Natspecc comment for this function");
|
"Should not have gotten a Natspecc comment for this function");
|
||||||
@ -205,8 +233,9 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation)
|
|||||||
" /// This is test function 4\n"
|
" /// This is test function 4\n"
|
||||||
" function functionName4(bytes32 input) returns (bytes32 out) {}\n"
|
" function functionName4(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
|
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
checkFunctionNatspec(function, "This is test function 1");
|
checkFunctionNatspec(function, "This is test function 1");
|
||||||
@ -232,9 +261,9 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation)
|
|||||||
" /// and it has 2 lines\n"
|
" /// and it has 2 lines\n"
|
||||||
" function functionName1(bytes32 input) returns (bytes32 out) {}\n"
|
" function functionName1(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
checkFunctionNatspec(function, "This is a test function\n"
|
checkFunctionNatspec(function, "This is a test function\n"
|
||||||
" and it has 2 lines");
|
" and it has 2 lines");
|
||||||
@ -257,8 +286,9 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
|
|||||||
" /// and it has 2 lines\n"
|
" /// and it has 2 lines\n"
|
||||||
" function fun(bytes32 input) returns (bytes32 out) {}\n"
|
" function fun(bytes32 input) returns (bytes32 out) {}\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
|
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
checkFunctionNatspec(function, "fun1 description");
|
checkFunctionNatspec(function, "fun1 description");
|
||||||
@ -283,8 +313,9 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
|
|||||||
" bytes7 name = \"Solidity\";"
|
" bytes7 name = \"Solidity\";"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
|
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
BOOST_CHECK_MESSAGE(!function->documentation(),
|
BOOST_CHECK_MESSAGE(!function->documentation(),
|
||||||
@ -306,8 +337,9 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
|
|||||||
" bytes7 name = \"Solidity\";"
|
" bytes7 name = \"Solidity\";"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
auto functions = contract->definedFunctions();
|
ErrorList errors;
|
||||||
|
auto functions = parseText(text, errors)->definedFunctions();
|
||||||
|
|
||||||
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function");
|
||||||
BOOST_CHECK_MESSAGE(!function->documentation(),
|
BOOST_CHECK_MESSAGE(!function->documentation(),
|
||||||
@ -323,7 +355,7 @@ BOOST_AUTO_TEST_CASE(struct_definition)
|
|||||||
" uint256 count;\n"
|
" uint256 count;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mapping)
|
BOOST_AUTO_TEST_CASE(mapping)
|
||||||
@ -331,7 +363,7 @@ BOOST_AUTO_TEST_CASE(mapping)
|
|||||||
char const* text = "contract test {\n"
|
char const* text = "contract test {\n"
|
||||||
" mapping(address => bytes32) names;\n"
|
" mapping(address => bytes32) names;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mapping_in_struct)
|
BOOST_AUTO_TEST_CASE(mapping_in_struct)
|
||||||
@ -343,7 +375,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_struct)
|
|||||||
" mapping(bytes32 => test_struct) self_reference;\n"
|
" mapping(bytes32 => test_struct) self_reference;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct)
|
BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct)
|
||||||
@ -354,7 +386,7 @@ BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct)
|
|||||||
" mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n"
|
" mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variable_definition)
|
BOOST_AUTO_TEST_CASE(variable_definition)
|
||||||
@ -367,7 +399,7 @@ BOOST_AUTO_TEST_CASE(variable_definition)
|
|||||||
" customtype varname;\n"
|
" customtype varname;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
|
BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
|
||||||
@ -381,7 +413,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
|
|||||||
" customtype varname;\n"
|
" customtype varname;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
|
BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
|
||||||
@ -391,7 +423,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
|
|||||||
function fun(var a) {}
|
function fun(var a) {}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
|
BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
|
||||||
@ -403,7 +435,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
|
BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
|
||||||
@ -415,7 +447,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(operator_expression)
|
BOOST_AUTO_TEST_CASE(operator_expression)
|
||||||
@ -425,7 +457,7 @@ BOOST_AUTO_TEST_CASE(operator_expression)
|
|||||||
" uint256 x = (1 + 4) || false && (1 - 12) + -9;\n"
|
" uint256 x = (1 + 4) || false && (1 - 12) + -9;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(complex_expression)
|
BOOST_AUTO_TEST_CASE(complex_expression)
|
||||||
@ -435,7 +467,7 @@ BOOST_AUTO_TEST_CASE(complex_expression)
|
|||||||
" uint256 x = (1 + 4).member(++67)[a/=9] || true;\n"
|
" uint256 x = (1 + 4).member(++67)[a/=9] || true;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(exp_expression)
|
BOOST_AUTO_TEST_CASE(exp_expression)
|
||||||
@ -446,7 +478,7 @@ BOOST_AUTO_TEST_CASE(exp_expression)
|
|||||||
uint256 x = 3 ** a;
|
uint256 x = 3 ** a;
|
||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(while_loop)
|
BOOST_AUTO_TEST_CASE(while_loop)
|
||||||
@ -456,7 +488,7 @@ BOOST_AUTO_TEST_CASE(while_loop)
|
|||||||
" while (true) { uint256 x = 1; break; continue; } x = 9;\n"
|
" while (true) { uint256 x = 1; break; continue; } x = 9;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr)
|
BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr)
|
||||||
@ -467,7 +499,7 @@ BOOST_AUTO_TEST_CASE(for_loop_vardef_initexpr)
|
|||||||
" { uint256 x = i; break; continue; }\n"
|
" { uint256 x = i; break; continue; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
|
BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
|
||||||
@ -479,7 +511,7 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_initexpr)
|
|||||||
" { uint256 x = i; break; continue; }\n"
|
" { uint256 x = i; break; continue; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
|
BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
|
||||||
@ -491,7 +523,7 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_noexpr)
|
|||||||
" { uint256 x = i; break; continue; }\n"
|
" { uint256 x = i; break; continue; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body)
|
BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body)
|
||||||
@ -503,7 +535,7 @@ BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body)
|
|||||||
" continue;\n"
|
" continue;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(if_statement)
|
BOOST_AUTO_TEST_CASE(if_statement)
|
||||||
@ -513,7 +545,7 @@ BOOST_AUTO_TEST_CASE(if_statement)
|
|||||||
" if (a >= 8) return 2; else { var b = 7; }\n"
|
" if (a >= 8) return 2; else { var b = 7; }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(else_if_statement)
|
BOOST_AUTO_TEST_CASE(else_if_statement)
|
||||||
@ -523,7 +555,7 @@ BOOST_AUTO_TEST_CASE(else_if_statement)
|
|||||||
" if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n"
|
" if (a < 0) b = 0x67; else if (a == 0) b = 0x12; else b = 0x78;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)
|
BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)
|
||||||
@ -535,7 +567,7 @@ BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)
|
|||||||
" uint64[](3);\n"
|
" uint64[](3);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)
|
BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)
|
||||||
@ -545,7 +577,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)
|
|||||||
" var x = uint64[](3);\n"
|
" var x = uint64[](3);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(import_directive)
|
BOOST_AUTO_TEST_CASE(import_directive)
|
||||||
@ -556,7 +588,7 @@ BOOST_AUTO_TEST_CASE(import_directive)
|
|||||||
" uint64(2);\n"
|
" uint64(2);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multiple_contracts)
|
BOOST_AUTO_TEST_CASE(multiple_contracts)
|
||||||
@ -571,7 +603,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts)
|
|||||||
" uint64(2);\n"
|
" uint64(2);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)
|
BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)
|
||||||
@ -589,7 +621,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)
|
|||||||
" }\n"
|
" }\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"import \"ghi\";\n";
|
"import \"ghi\";\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(contract_inheritance)
|
BOOST_AUTO_TEST_CASE(contract_inheritance)
|
||||||
@ -604,7 +636,7 @@ BOOST_AUTO_TEST_CASE(contract_inheritance)
|
|||||||
" uint64(2);\n"
|
" uint64(2);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance)
|
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance)
|
||||||
@ -619,7 +651,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance)
|
|||||||
" uint64(2);\n"
|
" uint64(2);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments)
|
BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments)
|
||||||
@ -634,7 +666,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments)
|
|||||||
" uint64(2);\n"
|
" uint64(2);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(placeholder_in_function_context)
|
BOOST_AUTO_TEST_CASE(placeholder_in_function_context)
|
||||||
@ -645,7 +677,7 @@ BOOST_AUTO_TEST_CASE(placeholder_in_function_context)
|
|||||||
" return _ + 1;"
|
" return _ + 1;"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifier)
|
BOOST_AUTO_TEST_CASE(modifier)
|
||||||
@ -653,7 +685,7 @@ BOOST_AUTO_TEST_CASE(modifier)
|
|||||||
char const* text = "contract c {\n"
|
char const* text = "contract c {\n"
|
||||||
" modifier mod { if (msg.sender == 0) _ }\n"
|
" modifier mod { if (msg.sender == 0) _ }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifier_arguments)
|
BOOST_AUTO_TEST_CASE(modifier_arguments)
|
||||||
@ -661,7 +693,7 @@ BOOST_AUTO_TEST_CASE(modifier_arguments)
|
|||||||
char const* text = "contract c {\n"
|
char const* text = "contract c {\n"
|
||||||
" modifier mod(uint a) { if (msg.sender == a) _ }\n"
|
" modifier mod(uint a) { if (msg.sender == a) _ }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(modifier_invocation)
|
BOOST_AUTO_TEST_CASE(modifier_invocation)
|
||||||
@ -671,7 +703,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation)
|
|||||||
" modifier mod2 { if (msg.sender == 2) _ }\n"
|
" modifier mod2 { if (msg.sender == 2) _ }\n"
|
||||||
" function f() mod1(7) mod2 { }\n"
|
" function f() mod1(7) mod2 { }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fallback_function)
|
BOOST_AUTO_TEST_CASE(fallback_function)
|
||||||
@ -679,7 +711,7 @@ BOOST_AUTO_TEST_CASE(fallback_function)
|
|||||||
char const* text = "contract c {\n"
|
char const* text = "contract c {\n"
|
||||||
" function() { }\n"
|
" function() { }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(event)
|
BOOST_AUTO_TEST_CASE(event)
|
||||||
@ -688,7 +720,7 @@ BOOST_AUTO_TEST_CASE(event)
|
|||||||
contract c {
|
contract c {
|
||||||
event e();
|
event e();
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(event_arguments)
|
BOOST_AUTO_TEST_CASE(event_arguments)
|
||||||
@ -697,7 +729,7 @@ BOOST_AUTO_TEST_CASE(event_arguments)
|
|||||||
contract c {
|
contract c {
|
||||||
event e(uint a, bytes32 s);
|
event e(uint a, bytes32 s);
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(event_arguments_indexed)
|
BOOST_AUTO_TEST_CASE(event_arguments_indexed)
|
||||||
@ -706,7 +738,7 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed)
|
|||||||
contract c {
|
contract c {
|
||||||
event e(uint a, bytes32 indexed s, bool indexed b);
|
event e(uint a, bytes32 indexed s, bool indexed b);
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(visibility_specifiers)
|
BOOST_AUTO_TEST_CASE(visibility_specifiers)
|
||||||
@ -722,7 +754,7 @@ BOOST_AUTO_TEST_CASE(visibility_specifiers)
|
|||||||
function f_public() public {}
|
function f_public() public {}
|
||||||
function f_internal() internal {}
|
function f_internal() internal {}
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
|
BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
|
||||||
@ -731,7 +763,7 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
|
|||||||
contract c {
|
contract c {
|
||||||
uint private internal a;
|
uint private internal a;
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
|
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
|
||||||
@ -750,7 +782,7 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
|
|||||||
uint256 c;
|
uint256 c;
|
||||||
uint256 d;
|
uint256 d;
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expressions)
|
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expressions)
|
||||||
@ -763,7 +795,7 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expression
|
|||||||
}
|
}
|
||||||
uint256 a;
|
uint256 a;
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(enum_valid_declaration)
|
BOOST_AUTO_TEST_CASE(enum_valid_declaration)
|
||||||
@ -777,7 +809,7 @@ BOOST_AUTO_TEST_CASE(enum_valid_declaration)
|
|||||||
}
|
}
|
||||||
uint256 a;
|
uint256 a;
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_enum_declaration)
|
BOOST_AUTO_TEST_CASE(empty_enum_declaration)
|
||||||
@ -786,7 +818,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration)
|
|||||||
contract c {
|
contract c {
|
||||||
enum foo { }
|
enum foo { }
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
|
BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
|
||||||
@ -795,7 +827,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration)
|
|||||||
contract c {
|
contract c {
|
||||||
enum foo { WARNING,}
|
enum foo { WARNING,}
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_function)
|
BOOST_AUTO_TEST_CASE(external_function)
|
||||||
@ -804,7 +836,7 @@ BOOST_AUTO_TEST_CASE(external_function)
|
|||||||
contract c {
|
contract c {
|
||||||
function x() external {}
|
function x() external {}
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(external_variable)
|
BOOST_AUTO_TEST_CASE(external_variable)
|
||||||
@ -813,10 +845,10 @@ BOOST_AUTO_TEST_CASE(external_variable)
|
|||||||
contract c {
|
contract c {
|
||||||
uint external x;
|
uint external x;
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(arrays_in_storage)
|
BOOST_AUTO_TEST_CASE(arrays_in_storagze)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract c {
|
contract c {
|
||||||
@ -825,7 +857,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_storage)
|
|||||||
struct x { uint[2**20] b; y[0] c; }
|
struct x { uint[2**20] b; y[0] c; }
|
||||||
struct y { uint d; mapping(uint=>x)[] e; }
|
struct y { uint d; mapping(uint=>x)[] e; }
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(arrays_in_events)
|
BOOST_AUTO_TEST_CASE(arrays_in_events)
|
||||||
@ -834,7 +866,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_events)
|
|||||||
contract c {
|
contract c {
|
||||||
event e(uint[10] a, bytes7[8] indexed b, c[3] x);
|
event e(uint[10] a, bytes7[8] indexed b, c[3] x);
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(arrays_in_expressions)
|
BOOST_AUTO_TEST_CASE(arrays_in_expressions)
|
||||||
@ -843,7 +875,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_expressions)
|
|||||||
contract c {
|
contract c {
|
||||||
function f() { c[10] a = 7; uint8[10 * 2] x; }
|
function f() { c[10] a = 7; uint8[10 * 2] x; }
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multi_arrays)
|
BOOST_AUTO_TEST_CASE(multi_arrays)
|
||||||
@ -852,7 +884,7 @@ BOOST_AUTO_TEST_CASE(multi_arrays)
|
|||||||
contract c {
|
contract c {
|
||||||
mapping(uint => mapping(uint => int8)[8][][9])[] x;
|
mapping(uint => mapping(uint => int8)[8][][9])[] x;
|
||||||
})";
|
})";
|
||||||
ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed");
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(constant_is_keyword)
|
BOOST_AUTO_TEST_CASE(constant_is_keyword)
|
||||||
@ -861,7 +893,7 @@ BOOST_AUTO_TEST_CASE(constant_is_keyword)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
uint constant = 4;
|
uint constant = 4;
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(var_array)
|
BOOST_AUTO_TEST_CASE(var_array)
|
||||||
@ -870,7 +902,7 @@ BOOST_AUTO_TEST_CASE(var_array)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
function f() { var[] a; }
|
function f() { var[] a; }
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(location_specifiers_for_params)
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_params)
|
||||||
@ -880,7 +912,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_params)
|
|||||||
function f(uint[] storage constant x, uint[] memory y) { }
|
function f(uint[] storage constant x, uint[] memory y) { }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(location_specifiers_for_locals)
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_locals)
|
||||||
@ -893,7 +925,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_locals)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(location_specifiers_for_state)
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_state)
|
||||||
@ -902,7 +934,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_state)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
uint[] memory x;
|
uint[] memory x;
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
|
BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
|
||||||
@ -911,7 +943,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
|
|||||||
contract Foo {
|
contract Foo {
|
||||||
function f() { var memory x; }
|
function f() { var memory x; }
|
||||||
})";
|
})";
|
||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(empty_comment)
|
BOOST_AUTO_TEST_CASE(empty_comment)
|
||||||
@ -921,7 +953,7 @@ BOOST_AUTO_TEST_CASE(empty_comment)
|
|||||||
contract test
|
contract test
|
||||||
{}
|
{}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
BOOST_CHECK(successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(library_simple)
|
BOOST_AUTO_TEST_CASE(library_simple)
|
||||||
@ -931,7 +963,21 @@ BOOST_AUTO_TEST_CASE(library_simple)
|
|||||||
function f() { }
|
function f() { }
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK_NO_THROW(parseText(text));
|
BOOST_CHECK(successParse(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(local_const_variable)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract Foo {
|
||||||
|
function localConst() returns (uint ret)
|
||||||
|
{
|
||||||
|
uint constant local = 4;
|
||||||
|
return local;
|
||||||
|
}
|
||||||
|
})";
|
||||||
|
BOOST_CHECK(!successParse(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(multi_variable_declaration)
|
BOOST_AUTO_TEST_CASE(multi_variable_declaration)
|
||||||
|
@ -67,12 +67,26 @@ public:
|
|||||||
return m_output;
|
return m_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Exceptiontype>
|
void compileRequireError(std::string const& _sourceCode, Error::Type _type)
|
||||||
void compileRequireThrow(std::string const& _sourceCode)
|
|
||||||
{
|
{
|
||||||
m_compiler.reset(false, m_addStandardSources);
|
m_compiler.reset(false, m_addStandardSources);
|
||||||
m_compiler.addSource("", _sourceCode);
|
m_compiler.addSource("", _sourceCode);
|
||||||
BOOST_REQUIRE_THROW(m_compiler.compile(m_optimize, m_optimizeRuns), Exceptiontype);
|
bool foundError = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_compiler.compile(m_optimize, m_optimizeRuns);
|
||||||
|
BOOST_REQUIRE(Error::containsErrorOfType(m_compiler.errors(), _type));
|
||||||
|
}
|
||||||
|
catch(Error const& _e)
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE(_e.type() == _type);
|
||||||
|
foundError = true;
|
||||||
|
}
|
||||||
|
catch(Exception const& _exception)
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE(false);
|
||||||
|
}
|
||||||
|
BOOST_REQUIRE(foundError);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes const& compileAndRun(
|
bytes const& compileAndRun(
|
||||||
|
Loading…
Reference in New Issue
Block a user