Browse Source

Fixes for named-args.

cl-refactor
Gav Wood 10 years ago
parent
commit
f6955b370e
  1. 2
      libsolidity/AST.cpp
  2. 6
      libsolidity/AST.h
  3. 21
      libsolidity/ExpressionCompiler.cpp
  4. 24
      libsolidity/Parser.cpp
  5. 2
      libsolidity/Parser.h

2
libsolidity/AST.cpp

@ -513,7 +513,7 @@ void FunctionCall::checkTypeRequirements()
for (size_t i = 0; i < m_names.size(); i++) { for (size_t i = 0; i < m_names.size(); i++) {
bool found = false; bool found = false;
for (size_t j = 0; j < parameterNames.size(); j++) { for (size_t j = 0; j < parameterNames.size(); j++) {
if (parameterNames[j] == m_names[i]) { if (parameterNames[j] == *m_names[i]) {
// check type convertible // check type convertible
if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j])) if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j]))
BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call.")); BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call."));

6
libsolidity/AST.h

@ -963,7 +963,7 @@ class FunctionCall: public Expression
{ {
public: public:
FunctionCall(Location const& _location, ASTPointer<Expression> const& _expression, 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) {} Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
@ -971,7 +971,7 @@ public:
Expression const& getExpression() const { return *m_expression; } Expression const& getExpression() const { return *m_expression; }
std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } 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 /// Returns true if this is not an actual function call, but an explicit type conversion
/// or constructor call. /// or constructor call.
@ -980,7 +980,7 @@ public:
private: private:
ASTPointer<Expression> m_expression; ASTPointer<Expression> m_expression;
std::vector<ASTPointer<Expression>> m_arguments; std::vector<ASTPointer<Expression>> m_arguments;
std::vector<std::string> m_names; std::vector<ASTPointer<ASTString>> m_names;
}; };
/** /**

21
libsolidity/ExpressionCompiler.cpp

@ -204,34 +204,25 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{ {
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType()); FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
TypePointers const& parameterTypes = function.getParameterTypes(); TypePointers const& parameterTypes = function.getParameterTypes();
vector<string> const& parameterNames = function.getParameterNames();
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments(); 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(), ""); solAssert(callArguments.size() == parameterTypes.size(), "");
vector<ASTPointer<Expression const>> arguments; vector<ASTPointer<Expression const>> arguments;
if (callArgumentNames.empty()) if (callArgumentNames.empty())
{
// normal arguments // normal arguments
arguments = {callArguments.begin(), callArguments.end()}; arguments = callArguments;
}
else else
{
// named arguments // named arguments
for (size_t i = 0; i < parameterNames.size(); i++) { for (auto const& parameterName: function.getParameterNames())
{
bool found = false; bool found = false;
for (size_t j = 0; j < callArgumentNames.size(); j++) { for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
if (parameterNames[i] == callArgumentNames[j]) { if ((found = (parameterName == *callArgumentNames[j])))
// we found the actual parameter position // we found the actual parameter position
arguments.push_back(callArguments[j]); arguments.push_back(callArguments[j]);
found = true;
break;
}
}
solAssert(found, ""); solAssert(found, "");
} }
}
switch (function.getLocation()) switch (function.getLocation())
{ {

24
libsolidity/Parser.cpp

@ -592,7 +592,6 @@ ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
ASTPointer<Expression> expression = parseUnaryExpression(); ASTPointer<Expression> expression = parseUnaryExpression();
int precedence = Token::precedence(m_scanner->getCurrentToken()); int precedence = Token::precedence(m_scanner->getCurrentToken());
for (; precedence >= _minPrecedence; --precedence) for (; precedence >= _minPrecedence; --precedence)
{
while (Token::precedence(m_scanner->getCurrentToken()) == precedence) while (Token::precedence(m_scanner->getCurrentToken()) == precedence)
{ {
Token::Value op = m_scanner->getCurrentToken(); Token::Value op = m_scanner->getCurrentToken();
@ -601,7 +600,6 @@ ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
nodeFactory.setEndPositionFromNode(right); nodeFactory.setEndPositionFromNode(right);
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right); expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
} }
}
return expression; return expression;
} }
@ -668,8 +666,8 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression()
{ {
m_scanner->next(); m_scanner->next();
vector<ASTPointer<Expression>> arguments; vector<ASTPointer<Expression>> arguments;
vector<string> names; vector<ASTPointer<ASTString>> names;
parseFunctionCallArguments(arguments, names); std::tie(arguments, names) = parseFunctionCallArguments();
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expectToken(Token::RPAREN); expectToken(Token::RPAREN);
expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names); expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names);
@ -740,8 +738,9 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()
return arguments; 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(); Token::Value token = m_scanner->getCurrentToken();
if (token == Token::LBRACE) if (token == Token::LBRACE)
{ {
@ -749,28 +748,21 @@ void Parser::parseFunctionCallArguments(vector<ASTPointer<Expression>>& _argumen
expectToken(Token::LBRACE); expectToken(Token::LBRACE);
while (m_scanner->getCurrentToken() != Token::RBRACE) while (m_scanner->getCurrentToken() != Token::RBRACE)
{ {
string identifier = *expectIdentifierToken();
expectToken(Token::COLON); expectToken(Token::COLON);
ASTPointer<Expression> expression = parseExpression();
_arguments.push_back(expression); ret.first.push_back(parseExpression());
_names.push_back(identifier); ret.second.push_back(expectIdentifierToken());
if (m_scanner->getCurrentToken() == Token::COMMA) if (m_scanner->getCurrentToken() == Token::COMMA)
{
expectToken(Token::COMMA); expectToken(Token::COMMA);
}
else else
{
break; break;
}
} }
expectToken(Token::RBRACE); expectToken(Token::RBRACE);
} }
else else
{ ret.first = parseFunctionCallListArguments();
_arguments = parseFunctionCallListArguments(); return ret;
}
} }

2
libsolidity/Parser.h

@ -82,7 +82,7 @@ private:
ASTPointer<Expression> parseLeftHandSideExpression(); ASTPointer<Expression> parseLeftHandSideExpression();
ASTPointer<Expression> parsePrimaryExpression(); ASTPointer<Expression> parsePrimaryExpression();
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments(); 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…
Cancel
Save