diff options
-rw-r--r-- | libsolidity/CompilerContext.cpp | 2 | ||||
-rw-r--r-- | libsolidity/CompilerStack.cpp | 32 | ||||
-rw-r--r-- | libsolidity/CompilerStack.h | 1 | ||||
-rw-r--r-- | libsolidity/Exceptions.h | 36 | ||||
-rw-r--r-- | libsolidity/NameAndTypeResolver.cpp | 240 | ||||
-rw-r--r-- | libsolidity/NameAndTypeResolver.h | 42 | ||||
-rw-r--r-- | libsolidity/Parser.cpp | 86 | ||||
-rw-r--r-- | libsolidity/Parser.h | 13 | ||||
-rw-r--r-- | libsolidity/TypeChecker.cpp | 30 | ||||
-rw-r--r-- | libsolidity/TypeChecker.h | 10 | ||||
-rw-r--r-- | solc/CommandLineInterface.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/Assembly.cpp | 14 | ||||
-rw-r--r-- | test/libsolidity/SolidityABIJSON.cpp | 7 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 4 | ||||
-rw-r--r-- | test/libsolidity/SolidityExpressionCompiler.cpp | 14 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 280 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 224 | ||||
-rw-r--r-- | test/libsolidity/solidityExecutionFramework.h | 20 |
18 files changed, 651 insertions, 406 deletions
diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index fa7f9c77..0ba7af5b 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -137,7 +137,7 @@ ModifierDefinition const& CompilerContext::functionModifier(string const& _name) if (modifier->name() == _name) return *modifier.get(); 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 diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index 519f785b..3887999a 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -97,30 +97,41 @@ void CompilerStack::setSource(string const& _sourceCode) bool CompilerStack::parse() { + // todo not sure about clear. can contain warnings m_errors.clear(); for (auto& sourcePair: m_sources) { 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(); m_globalContext = make_shared<GlobalContext>(); + bool success = true; NameAndTypeResolver resolver(m_globalContext->declarations(), m_errors); for (Source const* source: m_sourceOrder) - resolver.registerDeclarations(*source->ast); + success = success && resolver.registerDeclarations(*source->ast); for (Source const* source: m_sourceOrder) for (ASTPointer<ASTNode> const& node: source->ast->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { m_globalContext->setCurrentContract(*contract); - resolver.updateDeclaration(*m_globalContext->currentThis()); - resolver.updateDeclaration(*m_globalContext->currentSuper()); - resolver.resolveNamesAndTypes(*contract); + success = success && resolver.updateDeclaration(*m_globalContext->currentThis()); + success = success && resolver.updateDeclaration(*m_globalContext->currentSuper()); + success = success && resolver.resolveNamesAndTypes(*contract); m_contracts[contract->name()].contract = contract; } + if (!success) + { + m_parseSuccessful = false; + return m_parseSuccessful; + } InterfaceHandler interfaceHandler; bool typesFine = true; for (Source const* source: m_sourceOrder) @@ -137,6 +148,7 @@ bool CompilerStack::parse() } else typesFine = false; + m_contracts[contract->name()].contract = contract; m_errors += typeChecker.errors(); } @@ -253,9 +265,8 @@ string const& CompilerStack::metadata(string const& _contractName, Documentation if (!m_parseSuccessful) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); - Contract const& currentContract = contract(_contractName); - std::unique_ptr<string const>* doc; + Contract const& currentContract = contract(_contractName); // checks wheather we already have the documentation switch (_type) @@ -346,9 +357,10 @@ void CompilerStack::resolveImports() if (!m_sources.count(id)) BOOST_THROW_EXCEPTION( Error(Error::Type::ParserError) - << errinfo_sourceLocation(import->location()) - << errinfo_comment("Source not found.") + << errinfo_sourceLocation(import->location()) + << errinfo_comment("Source not found.") ); + toposort(&m_sources[id]); } sourceOrder.push_back(_source); @@ -414,10 +426,12 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co auto it = m_sources.find(_sourceName); if (it == m_sources.end()) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Given source file not found.")); + return it->second; } CompilerStack::Contract::Contract(): interfaceHandler(make_shared<InterfaceHandler>()) {} + } } diff --git a/libsolidity/CompilerStack.h b/libsolidity/CompilerStack.h index 5b128868..e47f558b 100644 --- a/libsolidity/CompilerStack.h +++ b/libsolidity/CompilerStack.h @@ -167,6 +167,7 @@ public: /// @returns the list of errors that occured during parsing and type checking. ErrorList const& errors() const { return m_errors; } + private: /** * Information pertaining to one source unit, filled gradually during parsing and compilation. diff --git a/libsolidity/Exceptions.h b/libsolidity/Exceptions.h index 5a1b827c..92c009ef 100644 --- a/libsolidity/Exceptions.h +++ b/libsolidity/Exceptions.h @@ -26,11 +26,18 @@ #include <utility> #include <libdevcore/Exceptions.h> #include <libevmasm/SourceLocation.h> +#include <libsolidity/Utils.h> namespace dev { 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 { @@ -41,7 +48,6 @@ public: DocstringParsingError, ParserError, TypeError, - Warning }; @@ -65,22 +71,39 @@ public: m_typeName = "Warning"; break; default: - m_typeName = "Error"; + solAssert(false, ""); break; } } - Type const type() { return m_type; } const + Type type() const { return m_type; } 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: Type m_type; std::string m_typeName; }; -struct CompilerError: virtual Exception {}; -struct InternalCompilerError: virtual Exception {}; -struct FatalError: virtual Exception {}; 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_secondarySourceLocation = boost::error_info<struct tag_secondarySourceLocation, SecondarySourceLocation>; diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 3591c07a..934be0e3 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -42,81 +42,105 @@ NameAndTypeResolver::NameAndTypeResolver( 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. - 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 + { + m_currentScope = &m_scopes[nullptr]; - for (ASTPointer<InheritanceSpecifier> const& baseContract: _contract.baseContracts()) - ReferencesResolver resolver(*baseContract, *this, &_contract, nullptr); + for (ASTPointer<InheritanceSpecifier> const& baseContract: _contract.baseContracts()) + ReferencesResolver resolver(*baseContract, *this, &_contract, nullptr); - m_currentScope = &m_scopes[&_contract]; + m_currentScope = &m_scopes[&_contract]; - linearizeBaseContracts(_contract); - std::vector<ContractDefinition const*> properBases( - ++_contract.annotation().linearizedBaseContracts.begin(), - _contract.annotation().linearizedBaseContracts.end() - ); + linearizeBaseContracts(_contract); + std::vector<ContractDefinition const*> properBases( + ++_contract.annotation().linearizedBaseContracts.begin(), + _contract.annotation().linearizedBaseContracts.end() + ); - for (ContractDefinition const* base: properBases) - importInheritedScope(*base); + 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); + 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()]; - 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() - ); - } + // 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]; + 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); + // 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()]; - ReferencesResolver referencesResolver( - *function, - *this, - &_contract, - function->returnParameterList().get(), - true - ); + return false; } + return true; } -void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) +bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) { - m_scopes[nullptr].registerDeclaration(_declaration, false, true); - solAssert(_declaration.scope() == nullptr, "Updated declaration outside global scope."); + try + { + 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 @@ -164,11 +188,8 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations( FunctionType functionType(functionDefinition); for (auto parameter: functionType.parameterTypes() + functionType.returnParameterTypes()) if (!parameter) - BOOST_THROW_EXCEPTION( - Error(Error::Type::DeclarationError) << - errinfo_sourceLocation(_identifier.location()) << - errinfo_comment("Function type can not be used in this context") - ); + reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context"); + if (uniqueFunctions.end() == find_if( uniqueFunctions.begin(), uniqueFunctions.end(), @@ -194,7 +215,7 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) m_currentScope->registerDeclaration(*declaration); } -void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const +void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) { // order in the lists is from derived to base // 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(); auto base = dynamic_cast<ContractDefinition const*>(baseName.annotation().referencedDeclaration); 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 // mentioned earlier input.back().push_front(base); vector<ContractDefinition const*> const& basesBases = base->annotation().linearizedBaseContracts; 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.back().push_front(&_contract); vector<ContractDefinition const*> result = cThreeMerge(input); 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().contractDependencies.insert(result.begin() + 1, result.end()); } @@ -272,9 +293,53 @@ vector<_T const*> NameAndTypeResolver::cThreeMerge(list<list<_T const*>>& _toMer return result; } -DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, DeclarationContainer>& _scopes, - ASTNode& _astRoot): - m_scopes(_scopes), m_currentScope(nullptr) +void NameAndTypeResolver::reportDeclarationError( + SourceLocation _sourceLoction, + 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); } @@ -409,13 +474,11 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio secondDeclarationLocation = _declaration.location(); } - BOOST_THROW_EXCEPTION( - Error(Error::Type::DeclarationError) << - errinfo_sourceLocation(secondDeclarationLocation) << - errinfo_comment("Identifier already declared.") << - errinfo_secondarySourceLocation( - SecondarySourceLocation().append("The previous declaration is here:", firstDeclarationLocation) - ) + declarationError( + secondDeclarationLocation, + "Identifier already declared.", + firstDeclarationLocation, + "The previous declaration is here:" ); } @@ -440,5 +503,32 @@ string DeclarationRegistrationHelper::currentCanonicalName() const 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()); +} + } } diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index d5afb29a..9587fcfe 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -44,12 +44,15 @@ class NameAndTypeResolver: private boost::noncopyable public: NameAndTypeResolver(std::vector<Declaration const*> const& _globals, ErrorList& _errors); /// 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. - 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 /// 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, /// 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; /// returns the vector of declarations without repetitions - static std::vector<Declaration const*> cleanedDeclarations( + std::vector<Declaration const*> cleanedDeclarations( Identifier const& _identifier, std::vector<Declaration const*> const& _declarations ); @@ -78,8 +81,8 @@ private: /// into the current scope if they are not present already. void importInheritedScope(ContractDefinition const& _base); - /// Computes "C3-Linearization" of base contracts and stores it inside the contract. - void linearizeBaseContracts(ContractDefinition& _contract) const; + /// Computes "C3-Linearization" of base contracts and stores it inside the contract. Reports errors if any + void linearizeBaseContracts(ContractDefinition& _contract); /// 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. template <class _T> @@ -90,6 +93,21 @@ private: /// not contain code. 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; ErrorList& m_errors; }; @@ -101,7 +119,7 @@ private: class DeclarationRegistrationHelper: private ASTVisitor { public: - DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot); + DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot, ErrorList& _errors); private: bool visit(ContractDefinition& _contract) override; @@ -126,10 +144,20 @@ private: /// @returns the canonical name of the current scope. 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; Declaration const* m_currentScope; VariableScope* m_currentFunction; + ErrorList& m_errors; }; } diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index ce13098e..491af369 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -66,25 +66,35 @@ private: ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner) { - m_scanner = _scanner; - ASTNodeFactory nodeFactory(*this); - vector<ASTPointer<ASTNode>> nodes; - while (m_scanner->currentToken() != Token::EOS) - { - switch (auto token = m_scanner->currentToken()) + try{ + m_scanner = _scanner; + ASTNodeFactory nodeFactory(*this); + vector<ASTPointer<ASTNode>> nodes; + while (m_scanner->currentToken() != Token::EOS) { - case Token::Import: - nodes.push_back(parseImportDirective()); - break; - case Token::Contract: - case Token::Library: - nodes.push_back(parseContractDefinition(token == Token::Library)); - break; - default: - BOOST_THROW_EXCEPTION(createParserError(std::string("Expected import directive or contract definition."))); + switch (auto token = m_scanner->currentToken()) + { + case Token::Import: + nodes.push_back(parseImportDirective()); + break; + case Token::Contract: + case Token::Library: + nodes.push_back(parseContractDefinition(token == Token::Library)); + 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 @@ -107,7 +117,7 @@ ASTPointer<ImportDirective> Parser::parseImportDirective() ASTNodeFactory nodeFactory(*this); expectToken(Token::Import); 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(); nodeFactory.markEndPosition(); expectToken(Token::Semicolon); @@ -165,7 +175,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) else if (currentTokenValue == Token::Event) events.push_back(parseEventDefinition()); else - BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected.")); + fatalParserError(std::string("Function, variable, struct or modifier declaration expected.")); } nodeFactory.markEndPosition(); expectToken(Token::RBrace); @@ -249,7 +259,7 @@ ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(ASTString const* else if (Token::isVisibilitySpecifier(token)) { if (visibility != Declaration::Visibility::Default) - BOOST_THROW_EXCEPTION(createParserError("Multiple visibility specifiers.")); + fatalParserError(std::string("Multiple visibility specifiers.")); visibility = parseVisibilitySpecifier(token); } else @@ -326,7 +336,7 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition() break; expectToken(Token::Comma); if (m_scanner->currentToken() != Token::Identifier) - BOOST_THROW_EXCEPTION(createParserError("Expected Identifier after ','")); + fatalParserError(std::string("Expected Identifier after ','")); } nodeFactory.markEndPosition(); @@ -362,7 +372,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( if (_options.isStateVariable && Token::isVariableVisibilitySpecifier(token)) { if (visibility != Declaration::Visibility::Default) - BOOST_THROW_EXCEPTION(createParserError("Visibility already specified.")); + fatalParserError(std::string("Visibility already specified.")); visibility = parseVisibilitySpecifier(token); } else @@ -374,9 +384,9 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( else if (_options.allowLocationSpecifier && Token::isLocationSpecifier(token)) { if (location != VariableDeclaration::Location::Default) - BOOST_THROW_EXCEPTION(createParserError("Location already specified.")); + fatalParserError(std::string("Location already specified.")); if (!type) - BOOST_THROW_EXCEPTION(createParserError("Location specifier needs explicit type name.")); + fatalParserError(std::string("Location specifier needs explicit type name.")); location = ( token == Token::Memory ? VariableDeclaration::Location::Memory : @@ -513,7 +523,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) else if (token == Token::Var) { if (!_allowVar) - BOOST_THROW_EXCEPTION(createParserError("Expected explicit type name.")); + fatalParserError(std::string("Expected explicit type name.")); m_scanner->next(); } else if (token == Token::Mapping) @@ -532,7 +542,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar) type = nodeFactory.createNode<UserDefinedTypeName>(identifierPath); } else - BOOST_THROW_EXCEPTION(createParserError("Expected type name")); + fatalParserError(std::string("Expected type name")); if (type) // Parse "[...]" postfixes for arrays. @@ -555,7 +565,7 @@ ASTPointer<Mapping> Parser::parseMapping() expectToken(Token::Mapping); expectToken(Token::LParen); 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; keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->currentToken()); m_scanner->next(); @@ -1011,7 +1021,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression() m_scanner->next(); } else - BOOST_THROW_EXCEPTION(createParserError("Expected primary expression.")); + fatalParserError(std::string("Expected primary expression.")); break; } return expression; @@ -1122,7 +1132,7 @@ ASTPointer<Expression> Parser::expressionFromIndexAccessStructure( void Parser::expectToken(Token::Value _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(); } @@ -1130,7 +1140,7 @@ Token::Value Parser::expectAssignmentOperator() { Token::Value op = m_scanner->currentToken(); if (!Token::isAssignmentOp(op)) - BOOST_THROW_EXCEPTION(createParserError("Expected assignment operator")); + fatalParserError(std::string("Expected assignment operator")); m_scanner->next(); return op; } @@ -1138,7 +1148,7 @@ Token::Value Parser::expectAssignmentOperator() ASTPointer<ASTString> Parser::expectIdentifierToken() { if (m_scanner->currentToken() != Token::Identifier) - BOOST_THROW_EXCEPTION(createParserError("Expected identifier")); + fatalParserError(std::string("Expected identifier")); return getLiteralAndAdvance(); } @@ -1156,13 +1166,21 @@ ASTPointer<ParameterList> Parser::createEmptyParameterList() 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) << - errinfo_sourceLocation(SourceLocation(position(), position(), sourceName())) << - errinfo_comment(_description); + auto err = make_shared<Error>(Error::Type::ParserError); + *err << + 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()); +} } } diff --git a/libsolidity/Parser.h b/libsolidity/Parser.h index c9acb47d..3fc3768e 100644 --- a/libsolidity/Parser.h +++ b/libsolidity/Parser.h @@ -34,7 +34,8 @@ class Scanner; class Parser { public: - Parser() {} + Parser(ErrorList& errors): + m_errors(errors){}; ASTPointer<SourceUnit> parse(std::shared_ptr<Scanner> const& _scanner); 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). 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. - 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; /// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier. bool m_insideModifier = false; + /// The reference to the list of errors and warning to add errors/warnings during parsing + ErrorList& m_errors; }; } diff --git a/libsolidity/TypeChecker.cpp b/libsolidity/TypeChecker.cpp index e3264429..cc7ad2f3 100644 --- a/libsolidity/TypeChecker.cpp +++ b/libsolidity/TypeChecker.cpp @@ -36,24 +36,26 @@ bool TypeChecker::checkTypeRequirements(const ContractDefinition& _contract) { visit(_contract); } - catch (FatalError const&) + catch (fatalError const&) { // We got a fatal error which required to stop further type checking, but we can // continue normally from here. if (m_errors.empty()) throw; // Something is weird here, rather throw again. } - bool success = true; - for (auto const& it: m_errors) - { - Error const& e = dynamic_cast<Error const&>(it.get()); - if (e.type() != Error::Type::Warning) - { - success = false; - break; - } - } - return success; + +return Error::containsOnlyWarnings(m_errors); +// bool success = true; +// for (auto const& it: m_errors) +// { +// auto e = dynamic_cast<Error const*>(it.get()); +// if (e->type() != Error::Type::Warning) +// { +// success = false; +// break; +// } +// } +// return success; } 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) { - auto err = make_shared<Error>(Error(Error::Type::TypeError));; + auto err = make_shared<Error>(Error::Type::TypeError); *err << errinfo_sourceLocation(_node.location()) << 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) { typeError(_node, _description); - BOOST_THROW_EXCEPTION(FatalError()); + BOOST_THROW_EXCEPTION(fatalError()); } diff --git a/libsolidity/TypeChecker.h b/libsolidity/TypeChecker.h index c654c698..de095e3b 100644 --- a/libsolidity/TypeChecker.h +++ b/libsolidity/TypeChecker.h @@ -42,26 +42,26 @@ namespace solidity class TypeChecker: private ASTConstVisitor { 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. /// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings 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. TypePointer const& type(Expression const& _expression) const; /// @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) TypePointer const& type(VariableDeclaration const& _variable) const; +private: /// Adds a new error to the list of errors. void typeError(ASTNode const& _node, std::string const& _description); /// Adds a new error to the list of errors and throws to abort type checking. void fatalTypeError(ASTNode const& _node, std::string const& _description); -private: virtual bool visit(ContractDefinition const& _contract) override; /// Checks that two functions defined in this contract with the same name have different /// 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. void requireLValue(Expression const& _expression); - ErrorList m_errors; + ErrorList& m_errors; }; } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 42b65d4c..deae5928 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -496,7 +496,7 @@ bool CommandLineInterface::processInput() SourceReferenceFormatter::printExceptionInformation( cerr, *error, - (dynamic_pointer_cast<Warning const>(error)) ? "Warning" : "Error", *m_compiler + (error->type() == Error::Type::Warning) ? "Warning" : "Error", *m_compiler ); if (!successful) return false; diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index ca1e8980..f69ae680 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -48,21 +48,29 @@ namespace eth::AssemblyItems compileContract(const string& _sourceCode) { - Parser parser; + ErrorList errors; + Parser parser(errors); ASTPointer<SourceUnit> sourceUnit; 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); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + if (!Error::containsOnlyWarnings(errors)) + return AssemblyItems(); } for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { - TypeChecker checker; + TypeChecker checker(errors); BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract)); + if (!Error::containsOnlyWarnings(errors)) + return AssemblyItems(); } for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index f3004b5f..68f5a64a 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -45,9 +45,10 @@ public: m_reader.parse(generatedInterfaceString, generatedInterface); Json::Value expectedInterface; m_reader.parse(_expectedInterfaceString, expectedInterface); - BOOST_CHECK_MESSAGE(expectedInterface == generatedInterface, - "Expected:\n" << expectedInterface.toStyledString() << - "\n but got:\n" << generatedInterface.toStyledString()); + BOOST_CHECK_MESSAGE( + expectedInterface == generatedInterface, + "Expected:\n" << expectedInterface.toStyledString() << "\n but got:\n" << generatedInterface.toStyledString() + ); } private: diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 08f62963..cccca0ba 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -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" "}\n"; - compileRequireThrow<DocstringParsingError>(sourceCode); + compileRequireError(sourceCode, Error::Type::DocstringParsingError); } 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" "}\n"; - compileRequireThrow<DocstringParsingError>(sourceCode); + compileRequireError(sourceCode, Error::Type::DocstringParsingError); } diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 8134080e..4013581d 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -92,11 +92,13 @@ bytes compileFirstExpression( vector<shared_ptr<MagicVariableDeclaration const>> _globalDeclarations = {} ) { - Parser parser; ASTPointer<SourceUnit> sourceUnit; 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) { @@ -108,9 +110,9 @@ bytes compileFirstExpression( declarations.reserve(_globalDeclarations.size() + 1); for (ASTPointer<Declaration const> const& variable: _globalDeclarations) declarations.push_back(variable.get()); - /// TODO: - ErrorList errorList; - NameAndTypeResolver resolver(declarations, errorList); + + ErrorList errors; + NameAndTypeResolver resolver(declarations, errors); resolver.registerDeclarations(*sourceUnit); vector<ContractDefinition const*> inheritanceHierarchy; @@ -123,7 +125,7 @@ bytes compileFirstExpression( for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { - TypeChecker typeChecker; + TypeChecker typeChecker(errors); BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract)); } for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index cc990c1e..905b5ce1 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -44,16 +44,23 @@ namespace test namespace { -pair<ASTPointer<SourceUnit>, shared_ptr<Exception const>> +pair<ASTPointer<SourceUnit>, std::shared_ptr<Error::Type const>> parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false) { - Parser parser; + ErrorList errors; + Parser parser(errors); ASTPointer<SourceUnit> sourceUnit; - shared_ptr<Exception const> err; // catch exceptions for a transition period try { 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>(); NameAndTypeResolver resolver(globalContext->declarations()); resolver.registerDeclarations(*sourceUnit); @@ -71,51 +78,45 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false) { globalContext->setCurrentContract(*contract); resolver.updateDeclaration(*globalContext->currentThis()); - TypeChecker typeChecker; + + TypeChecker typeChecker(errors); bool success = typeChecker.checkTypeRequirements(*contract); 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)) - { - err = firstError; - break; - } - else if (_reportWarnings) - { - err = firstError; - break; - } + if ( + (_reportWarnings && currentError->type() == Error::Type::Warning) || + (!_reportWarnings && currentError->type() != Error::Type::Warning) + ) + return make_pair(sourceUnit, std::make_shared<Error::Type const>(currentError->type())); } } } - catch (ParserError const& _exception) - { - return make_pair(sourceUnit, make_shared<ParserError>(_exception)); - } - catch (DeclarationError const& _exception) + catch(Error const& _e) { - return make_pair(sourceUnit, make_shared<DeclarationError>(_exception)); + return make_pair(sourceUnit, std::make_shared<Error::Type const>(_e.type())); } - catch (TypeError const& _exception) + catch (Exception const& _exception) { - return make_pair(sourceUnit, make_shared<TypeError>(_exception)); + return make_pair(sourceUnit, nullptr); } - return make_pair(sourceUnit, err); + return make_pair(sourceUnit, nullptr); } ASTPointer<SourceUnit> parseAndAnalyse(string const& _source) { auto sourceAndError = parseAnalyseAndReturnError(_source); - BOOST_REQUIRE(!sourceAndError.second); + BOOST_REQUIRE(!!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); BOOST_REQUIRE(!!sourceAndError.second); - return sourceAndError.second; + BOOST_REQUIRE(!!sourceAndError.first); + return *sourceAndError.second; } 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_CASE(smoke_test) @@ -161,7 +158,7 @@ BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) " uint256 variable;\n" " uint128 variable;\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } 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" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(double_variable_declaration) @@ -178,7 +175,7 @@ BOOST_AUTO_TEST_CASE(double_variable_declaration) char const* text = "contract test {\n" " function f() { uint256 x; if (true) { uint256 x; } }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(name_shadowing) @@ -205,7 +202,7 @@ BOOST_AUTO_TEST_CASE(undeclared_name) " uint256 variable;\n" " function f(uint256 arg) { f(notfound); }" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(reference_to_later_declaration) @@ -225,7 +222,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive) " MyStructName x;\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) @@ -240,7 +237,7 @@ BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive) " MyStructName1 x;\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) @@ -287,7 +284,7 @@ BOOST_AUTO_TEST_CASE(type_checking_return_wrong_number) char const* text = "contract test {\n" " function f() returns (bool r1, bool r2) { return 1 >= 2; }" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } 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" " function f() returns (uint256 r) { return 1 >= 2; }" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } 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" " function f() { int32(2) == uint64(2); }" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(type_inference_explicit_conversion) @@ -356,7 +353,7 @@ BOOST_AUTO_TEST_CASE(balance_invalid) " address(0).balance = 7;\n" " }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(assignment_to_mapping) @@ -371,7 +368,7 @@ BOOST_AUTO_TEST_CASE(assignment_to_mapping) " data.map = a;\n" " }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(assignment_to_struct) @@ -395,7 +392,7 @@ BOOST_AUTO_TEST_CASE(returns_in_constructor) " function test() returns (uint a) {\n" " }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(forward_function_reference) @@ -483,7 +480,7 @@ BOOST_AUTO_TEST_CASE(create_abstract_contract) 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) @@ -527,7 +524,7 @@ BOOST_AUTO_TEST_CASE(redeclare_implemented_abstract_function_as_abstract) contract derived is base { 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) @@ -636,7 +633,7 @@ BOOST_AUTO_TEST_CASE(function_external_call_not_allowed_conversion) } 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) @@ -668,7 +665,7 @@ BOOST_AUTO_TEST_CASE(function_internal_not_allowed_conversion) g(a); } })"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(hash_collision_in_interface) @@ -679,7 +676,7 @@ BOOST_AUTO_TEST_CASE(hash_collision_in_interface) " function tgeo() {\n" " }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(inheritance_basic) @@ -713,7 +710,7 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance) contract A is B { } 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) @@ -741,7 +738,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_visibility) contract B { function f() internal {} } 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) @@ -750,7 +747,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_constness) contract B { function f() constant {} } 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) @@ -820,7 +817,7 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) 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) @@ -843,7 +840,7 @@ BOOST_AUTO_TEST_CASE(invalid_function_modifier_type) 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) @@ -884,7 +881,7 @@ BOOST_AUTO_TEST_CASE(illegal_modifier_override) contract A { modifier mod(uint 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) @@ -893,7 +890,7 @@ BOOST_AUTO_TEST_CASE(modifier_overrides_function) contract A { modifier 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) @@ -902,7 +899,7 @@ BOOST_AUTO_TEST_CASE(function_overrides_modifier) contract A { function 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) @@ -913,7 +910,7 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) 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) @@ -964,7 +961,7 @@ BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) "uint256 foo;\n" " function foo() {}\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } 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" " function foo() returns (uint256) { return Parent2.m_aMember1; }\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) @@ -1037,7 +1034,7 @@ BOOST_AUTO_TEST_CASE(state_variable_member_of_wrong_class2) " function foo() returns (uint256) { return Child.m_aMember2; }\n" " uint256 public m_aMember3;\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(fallback_function) @@ -1059,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments) 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) @@ -1071,7 +1068,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_twice) function() { x = 3; } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(fallback_function_inheritance) @@ -1104,7 +1101,7 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed) contract c { 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) @@ -1178,7 +1175,7 @@ BOOST_AUTO_TEST_CASE(access_to_internal_function) contract d { 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) @@ -1190,7 +1187,7 @@ BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility) contract d { 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) @@ -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 b() returns (uint r) { r = a({a: 1}); }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } 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 b() returns (uint r) { r = a({}); }\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) @@ -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 b() returns (uint r) { r = a({a: 1, a: 2}); }\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) @@ -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 b() returns (uint r) { r = a({a: 1, c: 2}); }\n" "}\n"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } 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; } })"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(disallow_declaration_of_void_type) { +<<<<<<< HEAD char const* sourceCode = "contract c { function f() { var (x) = f(); } }"; 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) @@ -1309,7 +1311,7 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units) } uint256 a; })"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent) @@ -1318,7 +1320,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent) contract test { 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) @@ -1327,7 +1329,7 @@ BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big) contract test { 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) @@ -1357,7 +1359,7 @@ BOOST_AUTO_TEST_CASE(enum_invalid_member_access) 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) @@ -1408,7 +1410,7 @@ BOOST_AUTO_TEST_CASE(enum_implicit_conversion_is_not_okay) uint64 b; } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(enum_duplicate_values) @@ -1418,7 +1420,7 @@ BOOST_AUTO_TEST_CASE(enum_duplicate_values) 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) @@ -1431,7 +1433,7 @@ BOOST_AUTO_TEST_CASE(private_visibility) 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) @@ -1444,7 +1446,7 @@ BOOST_AUTO_TEST_CASE(private_visibility_via_explicit_base_access) function g() { base.f(); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(external_visibility) @@ -1455,7 +1457,7 @@ BOOST_AUTO_TEST_CASE(external_visibility) function g() { f(); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(external_base_visibility) @@ -1468,7 +1470,7 @@ BOOST_AUTO_TEST_CASE(external_base_visibility) 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) @@ -1478,7 +1480,7 @@ BOOST_AUTO_TEST_CASE(external_argument_assign) 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) @@ -1488,7 +1490,7 @@ BOOST_AUTO_TEST_CASE(external_argument_increment) 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) @@ -1498,7 +1500,7 @@ BOOST_AUTO_TEST_CASE(external_argument_delete) 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) @@ -1520,7 +1522,7 @@ BOOST_AUTO_TEST_CASE(array_with_nonconstant_length) contract c { 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) @@ -1531,7 +1533,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types1) uint[] b; 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) @@ -1542,7 +1544,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types2) uint8[] b; 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) @@ -1575,7 +1577,7 @@ BOOST_AUTO_TEST_CASE(array_copy_with_different_types_dynamic_static) uint[80] b; 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) @@ -1584,7 +1586,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_int) contract c { 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) @@ -1593,7 +1595,7 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) contract c { uint a = "abc"; })"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) @@ -1718,7 +1720,7 @@ BOOST_AUTO_TEST_CASE(assigning_value_to_const_variable) function changeIt() { x = 9; } 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) @@ -1728,7 +1730,7 @@ BOOST_AUTO_TEST_CASE(complex_const_variable) contract Foo { 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) @@ -1737,20 +1739,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_const_variable) contract Foo { uint constant y; })"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), 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_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } 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); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } 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); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } 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); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } BOOST_AUTO_TEST_CASE(external_types_clash) @@ -1812,7 +1801,7 @@ BOOST_AUTO_TEST_CASE(external_types_clash) 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) @@ -1825,7 +1814,7 @@ BOOST_AUTO_TEST_CASE(override_changes_return_types) 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) @@ -1836,7 +1825,7 @@ BOOST_AUTO_TEST_CASE(multiple_constructors) function test() {} } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), DeclarationError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::DeclarationError); } BOOST_AUTO_TEST_CASE(equal_overload) @@ -1847,7 +1836,7 @@ BOOST_AUTO_TEST_CASE(equal_overload) 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) @@ -1857,7 +1846,7 @@ BOOST_AUTO_TEST_CASE(uninitialized_var) 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) @@ -1879,7 +1868,7 @@ BOOST_AUTO_TEST_CASE(string_index) 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) @@ -1890,7 +1879,7 @@ BOOST_AUTO_TEST_CASE(string_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) @@ -1900,7 +1889,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_signed_out_of_bound) 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) @@ -1920,7 +1909,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed_out_of_bound) 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) @@ -1940,7 +1929,7 @@ BOOST_AUTO_TEST_CASE(negative_integers_to_unsigned) 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) @@ -1950,7 +1939,7 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound) 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) @@ -1958,15 +1947,15 @@ BOOST_AUTO_TEST_CASE(integer_boolean_operators) char const* sourceCode1 = R"( 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"( 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"( 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) @@ -1974,11 +1963,11 @@ BOOST_AUTO_TEST_CASE(reference_compare_operators) char const* sourceCode1 = R"( 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"( 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) @@ -1988,7 +1977,7 @@ BOOST_AUTO_TEST_CASE(overwrite_memory_location_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) @@ -1998,7 +1987,7 @@ BOOST_AUTO_TEST_CASE(overwrite_storage_location_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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -2270,7 +2259,7 @@ BOOST_AUTO_TEST_CASE(inheriting_from_library) library 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) @@ -2279,7 +2268,7 @@ BOOST_AUTO_TEST_CASE(inheriting_library) contract 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) @@ -2287,7 +2276,7 @@ BOOST_AUTO_TEST_CASE(library_having_variables) char const* text = R"( library Lib { uint x; } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(text), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(text) == Error::Type::TypeError); } 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(); } } )"; - SOLIDITY_CHECK_ERROR_TYPE(parseAndAnalyseReturnError(sourceCode), TypeError); + BOOST_CHECK(parseAndAnalyseReturnErrorType(sourceCode) == Error::Type::TypeError); } 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) @@ -2345,7 +2334,7 @@ BOOST_AUTO_TEST_CASE(literal_string_to_storage_pointer) 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) @@ -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) diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index a90399fc..0bc4d4ee 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -39,10 +39,11 @@ namespace test namespace { -ASTPointer<ContractDefinition> parseText(std::string const& _source) +ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors) { - Parser parser; - ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source))); + ASTPointer<SourceUnit> sourceUnit = Parser(_errors).parse(std::make_shared<Scanner>(CharStream(_source))); + if(!sourceUnit) + return ASTPointer<ContractDefinition>(); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) if (ASTPointer<ContractDefinition> contract = dynamic_pointer_cast<ContractDefinition>(node)) return contract; @@ -50,8 +51,30 @@ ASTPointer<ContractDefinition> parseText(std::string const& _source) return ASTPointer<ContractDefinition>(); } -static void checkFunctionNatspec(ASTPointer<FunctionDefinition> _function, - std::string const& _expectedDoc) +bool successParse(std::string const& _source) +{ + 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(); 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" " uint256 stateVariable1;\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); + BOOST_CHECK(successParse(text)); } 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" " uint256 ;\n" "}\n"; - BOOST_CHECK_THROW(parseText(text), Error); + BOOST_CHECK(!successParse(text)); } BOOST_AUTO_TEST_CASE(empty_function) @@ -87,7 +110,7 @@ BOOST_AUTO_TEST_CASE(empty_function) " returns (int id)\n" " { }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(no_function_params) @@ -96,7 +119,7 @@ BOOST_AUTO_TEST_CASE(no_function_params) " uint256 stateVar;\n" " function functionName() {}\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(single_function_param) @@ -105,7 +128,7 @@ BOOST_AUTO_TEST_CASE(single_function_param) " uint256 stateVar;\n" " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(function_no_body) @@ -113,7 +136,7 @@ BOOST_AUTO_TEST_CASE(function_no_body) char const* text = "contract test {\n" " function functionName(bytes32 input) returns (bytes32 out);\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) @@ -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 b() returns (uint r) { r = a({: 1, : 2, : 3}); }\n" "}\n"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } 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 b() returns (uint r) { r = a({a: , b: , c: }); }\n" "}\n"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } 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, // we can't determine whether they match exactly, however // 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) @@ -156,20 +180,23 @@ BOOST_AUTO_TEST_CASE(overloaded_functions) 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) { - ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is a test function\n" " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + 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"); 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" " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(function->documentation() == nullptr, "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" " function functionName4(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "This is test function 1"); @@ -232,9 +261,9 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) " /// and it has 2 lines\n" " function functionName1(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); - + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "This is a test function\n" " and it has 2 lines"); @@ -257,8 +286,9 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) " /// and it has 2 lines\n" " function fun(bytes32 input) returns (bytes32 out) {}\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); checkFunctionNatspec(function, "fun1 description"); @@ -283,8 +313,9 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) " bytes7 name = \"Solidity\";" " }\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(!function->documentation(), @@ -306,8 +337,9 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) " bytes7 name = \"Solidity\";" " }\n" "}\n"; - ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); - auto functions = contract->definedFunctions(); + BOOST_CHECK(successParse(text)); + ErrorList errors; + auto functions = parseText(text, errors)->definedFunctions(); ETH_TEST_REQUIRE_NO_THROW(function = functions.at(0), "Failed to retrieve function"); BOOST_CHECK_MESSAGE(!function->documentation(), @@ -323,7 +355,7 @@ BOOST_AUTO_TEST_CASE(struct_definition) " uint256 count;\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(mapping) @@ -331,7 +363,7 @@ BOOST_AUTO_TEST_CASE(mapping) char const* text = "contract test {\n" " mapping(address => bytes32) names;\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(variable_definition) @@ -367,7 +399,7 @@ BOOST_AUTO_TEST_CASE(variable_definition) " customtype varname;\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) @@ -381,7 +413,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) " customtype varname;\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) @@ -391,7 +423,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter) function fun(var a) {} } )"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } 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) @@ -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) @@ -425,7 +457,7 @@ BOOST_AUTO_TEST_CASE(operator_expression) " uint256 x = (1 + 4) || false && (1 - 12) + -9;\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(exp_expression) @@ -446,7 +478,7 @@ BOOST_AUTO_TEST_CASE(exp_expression) uint256 x = 3 ** a; } })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) @@ -503,7 +535,7 @@ BOOST_AUTO_TEST_CASE(for_loop_single_stmt_body) " continue;\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } 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" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(import_directive) @@ -556,7 +588,7 @@ BOOST_AUTO_TEST_CASE(import_directive) " uint64(2);\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(multiple_contracts) @@ -571,7 +603,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts) " uint64(2);\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) @@ -589,7 +621,7 @@ BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) " }\n" "}\n" "import \"ghi\";\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(contract_inheritance) @@ -604,7 +636,7 @@ BOOST_AUTO_TEST_CASE(contract_inheritance) " uint64(2);\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) @@ -619,7 +651,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) " uint64(2);\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) @@ -634,7 +666,7 @@ BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments) " uint64(2);\n" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(placeholder_in_function_context) @@ -645,7 +677,7 @@ BOOST_AUTO_TEST_CASE(placeholder_in_function_context) " return _ + 1;" " }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier) @@ -653,7 +685,7 @@ BOOST_AUTO_TEST_CASE(modifier) char const* text = "contract c {\n" " modifier mod { if (msg.sender == 0) _ }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier_arguments) @@ -661,7 +693,7 @@ BOOST_AUTO_TEST_CASE(modifier_arguments) char const* text = "contract c {\n" " modifier mod(uint a) { if (msg.sender == a) _ }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(modifier_invocation) @@ -671,7 +703,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation) " modifier mod2 { if (msg.sender == 2) _ }\n" " function f() mod1(7) mod2 { }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(fallback_function) @@ -679,7 +711,7 @@ BOOST_AUTO_TEST_CASE(fallback_function) char const* text = "contract c {\n" " function() { }\n" "}\n"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(event) @@ -688,7 +720,7 @@ BOOST_AUTO_TEST_CASE(event) contract c { event e(); })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(event_arguments) @@ -697,7 +729,7 @@ BOOST_AUTO_TEST_CASE(event_arguments) contract c { 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) @@ -706,7 +738,7 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed) contract c { 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) @@ -722,7 +754,7 @@ BOOST_AUTO_TEST_CASE(visibility_specifiers) function f_public() public {} function f_internal() internal {} })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) @@ -731,7 +763,7 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) contract c { uint private internal a; })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } 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 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) @@ -763,7 +795,7 @@ BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations_in_expression } uint256 a; })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(enum_valid_declaration) @@ -777,7 +809,7 @@ BOOST_AUTO_TEST_CASE(enum_valid_declaration) } uint256 a; })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(empty_enum_declaration) @@ -786,7 +818,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) contract c { enum foo { } })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(malformed_enum_declaration) @@ -795,7 +827,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) contract c { enum foo { WARNING,} })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } BOOST_AUTO_TEST_CASE(external_function) @@ -804,7 +836,7 @@ BOOST_AUTO_TEST_CASE(external_function) contract c { function x() external {} })"; - ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(external_variable) @@ -813,10 +845,10 @@ BOOST_AUTO_TEST_CASE(external_variable) contract c { 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"( contract c { @@ -825,7 +857,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_storage) struct x { uint[2**20] b; y[0] c; } 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) @@ -834,7 +866,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_events) contract c { 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) @@ -843,7 +875,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_expressions) contract c { 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) @@ -852,7 +884,7 @@ BOOST_AUTO_TEST_CASE(multi_arrays) contract c { 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) @@ -861,7 +893,7 @@ BOOST_AUTO_TEST_CASE(constant_is_keyword) contract Foo { uint constant = 4; })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } BOOST_AUTO_TEST_CASE(var_array) @@ -870,7 +902,7 @@ BOOST_AUTO_TEST_CASE(var_array) contract Foo { function f() { var[] a; } })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } 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) { } } )"; - BOOST_CHECK_NO_THROW(parseText(text)); + BOOST_CHECK(successParse(text)); } 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) @@ -902,7 +934,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_state) contract Foo { uint[] memory x; })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } BOOST_AUTO_TEST_CASE(location_specifiers_with_var) @@ -911,7 +943,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_with_var) contract Foo { function f() { var memory x; } })"; - BOOST_CHECK_THROW(parseText(text), ParserError); + BOOST_CHECK(!successParse(text)); } BOOST_AUTO_TEST_CASE(empty_comment) @@ -921,7 +953,7 @@ BOOST_AUTO_TEST_CASE(empty_comment) contract test {} )"; - BOOST_CHECK_NO_THROW(parseText(text)); + BOOST_CHECK(successParse(text)); } BOOST_AUTO_TEST_CASE(library_simple) @@ -931,7 +963,21 @@ BOOST_AUTO_TEST_CASE(library_simple) 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) diff --git a/test/libsolidity/solidityExecutionFramework.h b/test/libsolidity/solidityExecutionFramework.h index 3370044c..27dd4fb7 100644 --- a/test/libsolidity/solidityExecutionFramework.h +++ b/test/libsolidity/solidityExecutionFramework.h @@ -67,12 +67,26 @@ public: return m_output; } - template <class Exceptiontype> - void compileRequireThrow(std::string const& _sourceCode) + void compileRequireError(std::string const& _sourceCode, Error::Type _type) { m_compiler.reset(false, m_addStandardSources); 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( |