mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fixes for named-args.
This commit is contained in:
parent
04164b612c
commit
2ff4a80b62
2
AST.cpp
2
AST.cpp
@ -513,7 +513,7 @@ void FunctionCall::checkTypeRequirements()
|
||||
for (size_t i = 0; i < m_names.size(); i++) {
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < parameterNames.size(); j++) {
|
||||
if (parameterNames[j] == m_names[i]) {
|
||||
if (parameterNames[j] == *m_names[i]) {
|
||||
// check type convertible
|
||||
if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j]))
|
||||
BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call."));
|
||||
|
6
AST.h
6
AST.h
@ -963,7 +963,7 @@ class FunctionCall: public Expression
|
||||
{
|
||||
public:
|
||||
FunctionCall(Location const& _location, ASTPointer<Expression> const& _expression,
|
||||
std::vector<ASTPointer<Expression>> const& _arguments, std::vector<std::string> const& _names):
|
||||
std::vector<ASTPointer<Expression>> const& _arguments, std::vector<ASTPointer<ASTString>> const& _names):
|
||||
Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
@ -971,7 +971,7 @@ public:
|
||||
|
||||
Expression const& getExpression() const { return *m_expression; }
|
||||
std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; }
|
||||
std::vector<std::string> const& getNames() const { return m_names; }
|
||||
std::vector<ASTPointer<ASTString>> const& getNames() const { return m_names; }
|
||||
|
||||
/// Returns true if this is not an actual function call, but an explicit type conversion
|
||||
/// or constructor call.
|
||||
@ -980,7 +980,7 @@ public:
|
||||
private:
|
||||
ASTPointer<Expression> m_expression;
|
||||
std::vector<ASTPointer<Expression>> m_arguments;
|
||||
std::vector<std::string> m_names;
|
||||
std::vector<ASTPointer<ASTString>> m_names;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -204,34 +204,25 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
{
|
||||
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
|
||||
TypePointers const& parameterTypes = function.getParameterTypes();
|
||||
vector<string> const& parameterNames = function.getParameterNames();
|
||||
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
|
||||
vector<string> const& callArgumentNames = _functionCall.getNames();
|
||||
vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
|
||||
solAssert(callArguments.size() == parameterTypes.size(), "");
|
||||
|
||||
vector<ASTPointer<Expression const>> arguments;
|
||||
if (callArgumentNames.empty())
|
||||
{
|
||||
// normal arguments
|
||||
arguments = {callArguments.begin(), callArguments.end()};
|
||||
}
|
||||
arguments = callArguments;
|
||||
else
|
||||
{
|
||||
// named arguments
|
||||
for (size_t i = 0; i < parameterNames.size(); i++) {
|
||||
for (auto const& parameterName: function.getParameterNames())
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < callArgumentNames.size(); j++) {
|
||||
if (parameterNames[i] == callArgumentNames[j]) {
|
||||
for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
|
||||
if ((found = (parameterName == *callArgumentNames[j])))
|
||||
// we found the actual parameter position
|
||||
arguments.push_back(callArguments[j]);
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
solAssert(found, "");
|
||||
}
|
||||
}
|
||||
|
||||
switch (function.getLocation())
|
||||
{
|
||||
|
24
Parser.cpp
24
Parser.cpp
@ -592,7 +592,6 @@ ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
ASTPointer<Expression> expression = parseUnaryExpression();
|
||||
int precedence = Token::precedence(m_scanner->getCurrentToken());
|
||||
for (; precedence >= _minPrecedence; --precedence)
|
||||
{
|
||||
while (Token::precedence(m_scanner->getCurrentToken()) == precedence)
|
||||
{
|
||||
Token::Value op = m_scanner->getCurrentToken();
|
||||
@ -601,7 +600,6 @@ ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
nodeFactory.setEndPositionFromNode(right);
|
||||
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
@ -668,8 +666,8 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression()
|
||||
{
|
||||
m_scanner->next();
|
||||
vector<ASTPointer<Expression>> arguments;
|
||||
vector<string> names;
|
||||
parseFunctionCallArguments(arguments, names);
|
||||
vector<ASTPointer<ASTString>> names;
|
||||
std::tie(arguments, names) = parseFunctionCallArguments();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RPAREN);
|
||||
expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names);
|
||||
@ -740,8 +738,9 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()
|
||||
return arguments;
|
||||
}
|
||||
|
||||
void Parser::parseFunctionCallArguments(vector<ASTPointer<Expression>>& _arguments, vector<string>& _names)
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseFunctionCallArguments()
|
||||
{
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
if (token == Token::LBRACE)
|
||||
{
|
||||
@ -749,28 +748,21 @@ void Parser::parseFunctionCallArguments(vector<ASTPointer<Expression>>& _argumen
|
||||
expectToken(Token::LBRACE);
|
||||
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
||||
{
|
||||
string identifier = *expectIdentifierToken();
|
||||
expectToken(Token::COLON);
|
||||
ASTPointer<Expression> expression = parseExpression();
|
||||
|
||||
_arguments.push_back(expression);
|
||||
_names.push_back(identifier);
|
||||
ret.first.push_back(parseExpression());
|
||||
ret.second.push_back(expectIdentifierToken());
|
||||
|
||||
if (m_scanner->getCurrentToken() == Token::COMMA)
|
||||
{
|
||||
expectToken(Token::COMMA);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
expectToken(Token::RBRACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
_arguments = parseFunctionCallListArguments();
|
||||
}
|
||||
ret.first = parseFunctionCallListArguments();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
2
Parser.h
2
Parser.h
@ -82,7 +82,7 @@ private:
|
||||
ASTPointer<Expression> parseLeftHandSideExpression();
|
||||
ASTPointer<Expression> parsePrimaryExpression();
|
||||
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();
|
||||
void parseFunctionCallArguments(std::vector<ASTPointer<Expression>> & _arguments, std::vector<std::string> & _names);
|
||||
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseFunctionCallArguments();
|
||||
///@}
|
||||
|
||||
///@{
|
||||
|
Loading…
Reference in New Issue
Block a user