mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Parse multi variable declaration statement.
This commit is contained in:
		
							parent
							
								
									2ba0002998
								
							
						
					
					
						commit
						67d208d144
					
				| @ -7,6 +7,7 @@ Features: | ||||
|  * Control Flow Graph: Add Control Flow Graph as analysis structure. | ||||
|  * Control Flow Graph: Warn about returning uninitialized storage pointers. | ||||
|  * Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation. | ||||
|  * General: Allow multiple variables to be declared as part of a tuple assignment, e.g. ``(uint a, uint b) = ...``. | ||||
|  * Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``). | ||||
|  * Parser: Display nicer error messages by showing the actual tokens and not internal names. | ||||
|  * Parser: Use the entire location of the token instead of only its starting position as source location for parser errors. | ||||
|  | ||||
| @ -1086,15 +1086,79 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& | ||||
| 	LookAheadInfo statementType; | ||||
| 	IndexAccessedPath iap; | ||||
| 
 | ||||
| 	tie(statementType, iap) = tryParseIndexAccessedPath(); | ||||
| 	switch (statementType) | ||||
| 	if (m_scanner->currentToken() == Token::LParen) | ||||
| 	{ | ||||
| 	case LookAheadInfo::VariableDeclaration: | ||||
| 		return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap)); | ||||
| 	case LookAheadInfo::Expression: | ||||
| 		return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap)); | ||||
| 	default: | ||||
| 		solAssert(false, ""); | ||||
| 		ASTNodeFactory nodeFactory(*this); | ||||
| 		size_t emptyComponents = 0; | ||||
| 		// First consume all empty components.
 | ||||
| 		expectToken(Token::LParen); | ||||
| 		while (m_scanner->currentToken() == Token::Comma) | ||||
| 		{ | ||||
| 			m_scanner->next(); | ||||
| 			emptyComponents++; | ||||
| 		} | ||||
| 
 | ||||
| 		// Now see whether we have a variable declaration or an expression.
 | ||||
| 		tie(statementType, iap) = tryParseIndexAccessedPath(); | ||||
| 		switch (statementType) | ||||
| 		{ | ||||
| 		case LookAheadInfo::VariableDeclaration: | ||||
| 		{ | ||||
| 			vector<ASTPointer<VariableDeclaration>> variables; | ||||
| 			ASTPointer<Expression> value; | ||||
| 			// We have already parsed something like `(,,,,a.b.c[2][3]`
 | ||||
| 			VarDeclParserOptions options; | ||||
| 			options.allowLocationSpecifier = true; | ||||
| 			variables = vector<ASTPointer<VariableDeclaration>>(emptyComponents, nullptr); | ||||
| 			variables.push_back(parseVariableDeclaration(options, typeNameFromIndexAccessStructure(iap))); | ||||
| 
 | ||||
| 			while (m_scanner->currentToken() != Token::RParen) | ||||
| 			{ | ||||
| 				expectToken(Token::Comma); | ||||
| 				if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen) | ||||
| 					variables.push_back(nullptr); | ||||
| 				else | ||||
| 					variables.push_back(parseVariableDeclaration(options)); | ||||
| 			} | ||||
| 			expectToken(Token::RParen); | ||||
| 			expectToken(Token::Assign); | ||||
| 			value = parseExpression(); | ||||
| 			nodeFactory.setEndPositionFromNode(value); | ||||
| 			return nodeFactory.createNode<VariableDeclarationStatement>(_docString, variables, value); | ||||
| 		} | ||||
| 		case LookAheadInfo::Expression: | ||||
| 		{ | ||||
| 			// Complete parsing the expression in the current component.
 | ||||
| 			vector<ASTPointer<Expression>> components(emptyComponents, nullptr); | ||||
| 			components.push_back(parseExpression(expressionFromIndexAccessStructure(iap))); | ||||
| 			while (m_scanner->currentToken() != Token::RParen) | ||||
| 			{ | ||||
| 				expectToken(Token::Comma); | ||||
| 				if (m_scanner->currentToken() == Token::Comma || m_scanner->currentToken() == Token::RParen) | ||||
| 					components.push_back(ASTPointer<Expression>()); | ||||
| 				else | ||||
| 					components.push_back(parseExpression()); | ||||
| 			} | ||||
| 			nodeFactory.markEndPosition(); | ||||
| 			expectToken(Token::RParen); | ||||
| 			return parseExpressionStatement(_docString, nodeFactory.createNode<TupleExpression>(components, false)); | ||||
| 		} | ||||
| 		default: | ||||
| 			solAssert(false, ""); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		tie(statementType, iap) = tryParseIndexAccessedPath(); | ||||
| 		switch (statementType) | ||||
| 		{ | ||||
| 		case LookAheadInfo::VariableDeclaration: | ||||
| 			return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap)); | ||||
| 		case LookAheadInfo::Expression: | ||||
| 			return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap)); | ||||
| 		default: | ||||
| 			solAssert(false, ""); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -1144,6 +1208,9 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme | ||||
| 	ASTPointer<TypeName> const& _lookAheadArrayType | ||||
| ) | ||||
| { | ||||
| 	// This does not parse multi variable declaration statements starting directly with
 | ||||
| 	// `(`, they are parsed in parseSimpleStatement, because they are hard to distinguish
 | ||||
| 	// from tuple expressions.
 | ||||
| 	RecursionGuard recursionGuard(*this); | ||||
| 	ASTNodeFactory nodeFactory(*this); | ||||
| 	if (_lookAheadArrayType) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user