mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' into library-constructor
This commit is contained in:
commit
01b4bba0ed
@ -10,6 +10,7 @@ Features:
|
|||||||
* Type Checker: Warn about shifting a literal.
|
* Type Checker: Warn about shifting a literal.
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
* Assembly Parser: Be more strict about number literals.
|
||||||
* Parser: Enforce commas between array and tuple elements.
|
* Parser: Enforce commas between array and tuple elements.
|
||||||
* Parser: Limit maximum recursion depth.
|
* Parser: Limit maximum recursion depth.
|
||||||
* Type Checker: Disallow constructors in libraries.
|
* Type Checker: Disallow constructors in libraries.
|
||||||
|
@ -16,7 +16,7 @@ ContractPart = StateVariableDeclaration | UsingForDeclaration
|
|||||||
|
|
||||||
InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* ')' )?
|
InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* ')' )?
|
||||||
|
|
||||||
StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' )? Identifier ('=' Expression)? ';'
|
StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';'
|
||||||
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
|
UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';'
|
||||||
StructDefinition = 'struct' Identifier '{'
|
StructDefinition = 'struct' Identifier '{'
|
||||||
( VariableDeclaration ';' (VariableDeclaration ';')* )? '}'
|
( VariableDeclaration ';' (VariableDeclaration ';')* )? '}'
|
||||||
@ -25,7 +25,7 @@ ModifierDefinition = 'modifier' Identifier ParameterList? Block
|
|||||||
ModifierInvocation = Identifier ( '(' ExpressionList? ')' )?
|
ModifierInvocation = Identifier ( '(' ExpressionList? ')' )?
|
||||||
|
|
||||||
FunctionDefinition = 'function' Identifier? ParameterList
|
FunctionDefinition = 'function' Identifier? ParameterList
|
||||||
( ModifierInvocation | 'constant' | 'payable' | 'external' | 'public' | 'internal' | 'private' )*
|
( ModifierInvocation | StateMutability | 'external' | 'public' | 'internal' | 'private' )*
|
||||||
( 'returns' ParameterList )? ( ';' | Block )
|
( 'returns' ParameterList )? ( ';' | Block )
|
||||||
EventDefinition = 'event' Identifier IndexedParameterList 'anonymous'? ';'
|
EventDefinition = 'event' Identifier IndexedParameterList 'anonymous'? ';'
|
||||||
|
|
||||||
@ -50,9 +50,10 @@ UserDefinedTypeName = Identifier ( '.' Identifier )*
|
|||||||
|
|
||||||
Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')'
|
Mapping = 'mapping' '(' ElementaryTypeName '=>' TypeName ')'
|
||||||
ArrayTypeName = TypeName '[' Expression? ']'
|
ArrayTypeName = TypeName '[' Expression? ']'
|
||||||
FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | 'constant' | 'payable' )*
|
FunctionTypeName = 'function' TypeNameList ( 'internal' | 'external' | StateMutability )*
|
||||||
( 'returns' TypeNameList )?
|
( 'returns' TypeNameList )?
|
||||||
StorageLocation = 'memory' | 'storage'
|
StorageLocation = 'memory' | 'storage'
|
||||||
|
StateMutability = 'constant' | 'payable'
|
||||||
|
|
||||||
Block = '{' Statement* '}'
|
Block = '{' Statement* '}'
|
||||||
Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
|
Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
|
||||||
|
@ -337,7 +337,7 @@ be passed via and returned from external function calls.
|
|||||||
|
|
||||||
Function types are notated as follows::
|
Function types are notated as follows::
|
||||||
|
|
||||||
function (<parameter types>) {internal|external} [constant] [payable] [returns (<return types>)]
|
function (<parameter types>) {internal|external} [constant|payable] [returns (<return types>)]
|
||||||
|
|
||||||
In contrast to the parameter types, the return types cannot be empty - if the
|
In contrast to the parameter types, the return types cannot be empty - if the
|
||||||
function type should not return anything, the whole ``returns (<return types>)``
|
function type should not return anything, the whole ``returns (<return types>)``
|
||||||
|
@ -57,7 +57,7 @@ class SolidityLexer(RegexLexer):
|
|||||||
(r'(anonymous|as|assembly|break|constant|continue|do|delete|else|external|for|hex|if|'
|
(r'(anonymous|as|assembly|break|constant|continue|do|delete|else|external|for|hex|if|'
|
||||||
r'indexed|internal|import|is|mapping|memory|new|payable|public|pragma|'
|
r'indexed|internal|import|is|mapping|memory|new|payable|public|pragma|'
|
||||||
r'private|return|returns|storage|super|this|throw|using|while)\b', Keyword, 'slashstartsregex'),
|
r'private|return|returns|storage|super|this|throw|using|while)\b', Keyword, 'slashstartsregex'),
|
||||||
(r'(var|function|event|modifier|struct|enum|contract|library)\b', Keyword.Declaration, 'slashstartsregex'),
|
(r'(var|function|event|modifier|struct|enum|contract|library|interface)\b', Keyword.Declaration, 'slashstartsregex'),
|
||||||
(r'(bytes|string|address|uint|int|bool|byte|' +
|
(r'(bytes|string|address|uint|int|bool|byte|' +
|
||||||
'|'.join(
|
'|'.join(
|
||||||
['uint%d' % (i + 8) for i in range(0, 256, 8)] +
|
['uint%d' % (i + 8) for i in range(0, 256, 8)] +
|
||||||
@ -71,7 +71,7 @@ class SolidityLexer(RegexLexer):
|
|||||||
r'null|of|pure|relocatable|static|switch|try|type|typeof|view)\b', Keyword.Reserved),
|
r'null|of|pure|relocatable|static|switch|try|type|typeof|view)\b', Keyword.Reserved),
|
||||||
(r'(true|false)\b', Keyword.Constant),
|
(r'(true|false)\b', Keyword.Constant),
|
||||||
(r'(block|msg|tx|now|suicide|selfdestruct|addmod|mulmod|sha3|keccak256|log[0-4]|'
|
(r'(block|msg|tx|now|suicide|selfdestruct|addmod|mulmod|sha3|keccak256|log[0-4]|'
|
||||||
r'sha256|ecrecover|ripemd160|assert|revert)', Name.Builtin),
|
r'sha256|ecrecover|ripemd160|assert|revert|require)', Name.Builtin),
|
||||||
(r'[$a-zA-Z_][a-zA-Z0-9_]*', Name.Other),
|
(r'[$a-zA-Z_][a-zA-Z0-9_]*', Name.Other),
|
||||||
(r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
|
(r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
|
||||||
(r'0x[0-9a-fA-F]+', Number.Hex),
|
(r'0x[0-9a-fA-F]+', Number.Hex),
|
||||||
|
@ -23,6 +23,9 @@
|
|||||||
#include <libsolidity/inlineasm/AsmParser.h>
|
#include <libsolidity/inlineasm/AsmParser.h>
|
||||||
#include <libsolidity/parsing/Scanner.h>
|
#include <libsolidity/parsing/Scanner.h>
|
||||||
#include <libsolidity/interface/ErrorReporter.h>
|
#include <libsolidity/interface/ErrorReporter.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -297,6 +300,8 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
|
|||||||
kind = LiteralKind::String;
|
kind = LiteralKind::String;
|
||||||
break;
|
break;
|
||||||
case Token::Number:
|
case Token::Number:
|
||||||
|
if (!isValidNumberLiteral(currentLiteral()))
|
||||||
|
fatalParserError("Invalid number literal.");
|
||||||
kind = LiteralKind::Number;
|
kind = LiteralKind::Number;
|
||||||
break;
|
break;
|
||||||
case Token::TrueLiteral:
|
case Token::TrueLiteral:
|
||||||
@ -501,3 +506,19 @@ string Parser::expectAsmIdentifier()
|
|||||||
expectToken(Token::Identifier);
|
expectToken(Token::Identifier);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::isValidNumberLiteral(string const& _literal)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
u256(_literal);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (boost::starts_with(_literal, "0x"))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return _literal.find_first_not_of("0123456789") == string::npos;
|
||||||
|
}
|
||||||
|
@ -75,6 +75,8 @@ protected:
|
|||||||
TypedName parseTypedName();
|
TypedName parseTypedName();
|
||||||
std::string expectAsmIdentifier();
|
std::string expectAsmIdentifier();
|
||||||
|
|
||||||
|
static bool isValidNumberLiteral(std::string const& _literal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_julia = false;
|
bool m_julia = false;
|
||||||
};
|
};
|
||||||
|
@ -214,6 +214,14 @@ BOOST_AUTO_TEST_CASE(invalid_types)
|
|||||||
CHECK_ERROR("{ function f(a:invalid) {} }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported).");
|
CHECK_ERROR("{ function f(a:invalid) {} }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported).");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(number_literals)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }"));
|
||||||
|
CHECK_ERROR("{ let x:u256 := .1:u256 }", ParserError, "Invalid number literal.");
|
||||||
|
CHECK_ERROR("{ let x:u256 := 1e5:u256 }", ParserError, "Invalid number literal.");
|
||||||
|
CHECK_ERROR("{ let x:u256 := 67.235:u256 }", ParserError, "Invalid number literal.");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(builtin_types)
|
BOOST_AUTO_TEST_CASE(builtin_types)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(successParse("{ let x:bool := true:bool }"));
|
BOOST_CHECK(successParse("{ let x:bool := true:bool }"));
|
||||||
|
@ -339,6 +339,14 @@ BOOST_AUTO_TEST_CASE(blocks)
|
|||||||
BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }"));
|
BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(number_literals)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(successParse("{ let x := 1 }"));
|
||||||
|
CHECK_PARSE_ERROR("{ let x := .1 }", ParserError, "Invalid number literal.");
|
||||||
|
CHECK_PARSE_ERROR("{ let x := 1e5 }", ParserError, "Invalid number literal.");
|
||||||
|
CHECK_PARSE_ERROR("{ let x := 67.235 }", ParserError, "Invalid number literal.");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(function_definitions)
|
BOOST_AUTO_TEST_CASE(function_definitions)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }"));
|
BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }"));
|
||||||
|
Loading…
Reference in New Issue
Block a user