Skip to content

Commit d4e2c2c

Browse files
authored
Merge pull request #13185 from ethereum/functionCall_locations
Add location for parameter names in FunctionCall ASTNode
2 parents 5de5120 + 3a5218d commit d4e2c2c

14 files changed

+103
-25
lines changed

libsolidity/ast/AST.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,9 +2105,14 @@ class FunctionCall: public Expression
21052105
SourceLocation const& _location,
21062106
ASTPointer<Expression> _expression,
21072107
std::vector<ASTPointer<Expression>> _arguments,
2108-
std::vector<ASTPointer<ASTString>> _names
2108+
std::vector<ASTPointer<ASTString>> _names,
2109+
std::vector<SourceLocation> _nameLocations
21092110
):
2110-
Expression(_id, _location), m_expression(std::move(_expression)), m_arguments(std::move(_arguments)), m_names(std::move(_names)) {}
2111+
Expression(_id, _location), m_expression(std::move(_expression)), m_arguments(std::move(_arguments)), m_names(std::move(_names)), m_nameLocations(std::move(_nameLocations))
2112+
{
2113+
solAssert(m_nameLocations.size() == m_names.size());
2114+
}
2115+
21112116
void accept(ASTVisitor& _visitor) override;
21122117
void accept(ASTConstVisitor& _visitor) const override;
21132118

@@ -2120,13 +2125,15 @@ class FunctionCall: public Expression
21202125
/// in the order they were written.
21212126
/// If this is not a named call, this is empty.
21222127
std::vector<ASTPointer<ASTString>> const& names() const { return m_names; }
2128+
std::vector<SourceLocation> const& nameLocations() const { return m_nameLocations; }
21232129

21242130
FunctionCallAnnotation& annotation() const override;
21252131

21262132
private:
21272133
ASTPointer<Expression> m_expression;
21282134
std::vector<ASTPointer<Expression>> m_arguments;
21292135
std::vector<ASTPointer<ASTString>> m_names;
2136+
std::vector<SourceLocation> m_nameLocations;
21302137
};
21312138

21322139
/**

libsolidity/ast/ASTJsonExporter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location)
128128
return to_string(_location.start) + ":" + to_string(length) + ":" + (sourceIndexOpt.has_value() ? to_string(sourceIndexOpt.value()) : "-1");
129129
}
130130

131+
Json::Value ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const& _sourceLocations) const
132+
{
133+
Json::Value locations = Json::arrayValue;
134+
135+
for (SourceLocation const& location: _sourceLocations)
136+
locations.append(sourceLocationToString(location));
137+
138+
return locations;
139+
}
140+
131141
string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath)
132142
{
133143
return boost::algorithm::join(_namePath, ".");
@@ -843,6 +853,7 @@ bool ASTJsonExporter::visit(FunctionCall const& _node)
843853
std::vector<pair<string, Json::Value>> attributes = {
844854
make_pair("expression", toJson(_node.expression())),
845855
make_pair("names", std::move(names)),
856+
make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())),
846857
make_pair("arguments", toJson(_node.arguments())),
847858
make_pair("tryCall", _node.annotation().tryCall)
848859
};

libsolidity/ast/ASTJsonExporter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class ASTJsonExporter: public ASTConstVisitor
144144
/// Maps source location to an index, if source is valid and a mapping does exist, otherwise returns std::nullopt.
145145
std::optional<size_t> sourceIndexFromLocation(langutil::SourceLocation const& _location) const;
146146
std::string sourceLocationToString(langutil::SourceLocation const& _location) const;
147+
Json::Value sourceLocationsToJson(std::vector<langutil::SourceLocation> const& _sourceLocations) const;
147148
static std::string namePathToString(std::vector<ASTString> const& _namePath);
148149
static Json::Value idOrNull(ASTNode const* _pt)
149150
{

libsolidity/ast/ASTJsonImporter.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _n
9595
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
9696
}
9797

98+
optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const
99+
{
100+
vector<SourceLocation> locations;
101+
102+
if (_node.isMember("nameLocations") && _node["nameLocations"].isArray())
103+
{
104+
for (auto const& val: _node["nameLocations"])
105+
locations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames));
106+
return locations;
107+
}
108+
109+
return nullopt;
110+
}
111+
98112
SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node)
99113
{
100114
astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string");
@@ -893,11 +907,17 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
893907
astAssert(name.isString(), "Expected 'names' members to be strings!");
894908
names.push_back(make_shared<ASTString>(name.asString()));
895909
}
910+
911+
optional<vector<SourceLocation>> sourceLocations = createSourceLocations(_node);
912+
896913
return createASTNode<FunctionCall>(
897914
_node,
898915
convertJsonToASTNode<Expression>(member(_node, "expression")),
899916
arguments,
900-
names
917+
names,
918+
sourceLocations ?
919+
*sourceLocations :
920+
vector<SourceLocation>(names.size())
901921
);
902922
}
903923

libsolidity/ast/ASTJsonImporter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ASTJsonImporter
5959
ASTPointer<T> createASTNode(Json::Value const& _node, Args&&... _args);
6060
/// @returns the sourceLocation-object created from the string in the JSON node
6161
langutil::SourceLocation const createSourceLocation(Json::Value const& _node);
62+
std::optional<std::vector<langutil::SourceLocation>> createSourceLocations(Json::Value const& _node) const;
6263
/// Creates an ASTNode for a given JSON-ast of unknown type
6364
/// @returns Pointer to a new created ASTNode
6465
ASTPointer<ASTNode> convertJsonToASTNode(Json::Value const& _ast);

libsolidity/parsing/Parser.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <cctype>
3939
#include <vector>
4040
#include <regex>
41+
#include <tuple>
4142

4243
using namespace std;
4344
using namespace solidity::langutil;
@@ -1542,13 +1543,16 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const
15421543
auto eventName = expressionFromIndexAccessStructure(iap);
15431544
expectToken(Token::LParen);
15441545

1545-
vector<ASTPointer<Expression>> arguments;
1546-
vector<ASTPointer<ASTString>> names;
1547-
std::tie(arguments, names) = parseFunctionCallArguments();
1546+
auto functionCallArguments = parseFunctionCallArguments();
15481547
eventCallNodeFactory.markEndPosition();
15491548
nodeFactory.markEndPosition();
15501549
expectToken(Token::RParen);
1551-
auto eventCall = eventCallNodeFactory.createNode<FunctionCall>(eventName, arguments, names);
1550+
auto eventCall = eventCallNodeFactory.createNode<FunctionCall>(
1551+
eventName,
1552+
functionCallArguments.arguments,
1553+
functionCallArguments.parameterNames,
1554+
functionCallArguments.parameterNameLocations
1555+
);
15521556
return nodeFactory.createNode<EmitStatement>(_docString, eventCall);
15531557
}
15541558

@@ -1573,13 +1577,16 @@ ASTPointer<RevertStatement> Parser::parseRevertStatement(ASTPointer<ASTString> c
15731577
auto errorName = expressionFromIndexAccessStructure(iap);
15741578
expectToken(Token::LParen);
15751579

1576-
vector<ASTPointer<Expression>> arguments;
1577-
vector<ASTPointer<ASTString>> names;
1578-
std::tie(arguments, names) = parseFunctionCallArguments();
1580+
auto functionCallArguments = parseFunctionCallArguments();
15791581
errorCallNodeFactory.markEndPosition();
15801582
nodeFactory.markEndPosition();
15811583
expectToken(Token::RParen);
1582-
auto errorCall = errorCallNodeFactory.createNode<FunctionCall>(errorName, arguments, names);
1584+
auto errorCall = errorCallNodeFactory.createNode<FunctionCall>(
1585+
errorName,
1586+
functionCallArguments.arguments,
1587+
functionCallArguments.parameterNames,
1588+
functionCallArguments.parameterNameLocations
1589+
);
15831590
return nodeFactory.createNode<RevertStatement>(_docString, errorCall);
15841591
}
15851592

@@ -1905,12 +1912,14 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
19051912
case Token::LParen:
19061913
{
19071914
advance();
1908-
vector<ASTPointer<Expression>> arguments;
1909-
vector<ASTPointer<ASTString>> names;
1910-
std::tie(arguments, names) = parseFunctionCallArguments();
1915+
auto functionCallArguments = parseFunctionCallArguments();
19111916
nodeFactory.markEndPosition();
19121917
expectToken(Token::RParen);
1913-
expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names);
1918+
expression = nodeFactory.createNode<FunctionCall>(
1919+
expression,
1920+
functionCallArguments.arguments,
1921+
functionCallArguments.parameterNames,
1922+
functionCallArguments.parameterNameLocations);
19141923
break;
19151924
}
19161925
case Token::LBrace:
@@ -1929,7 +1938,7 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
19291938
nodeFactory.markEndPosition();
19301939
expectToken(Token::RBrace);
19311940

1932-
expression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.first, optionList.second);
1941+
expression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.arguments, optionList.parameterNames);
19331942
break;
19341943
}
19351944
default:
@@ -2073,10 +2082,11 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()
20732082
return arguments;
20742083
}
20752084

2076-
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseFunctionCallArguments()
2085+
Parser::FunctionCallArguments Parser::parseFunctionCallArguments()
20772086
{
20782087
RecursionGuard recursionGuard(*this);
2079-
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
2088+
FunctionCallArguments ret;
2089+
20802090
Token token = m_scanner->currentToken();
20812091
if (token == Token::LBrace)
20822092
{
@@ -2086,23 +2096,29 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
20862096
expectToken(Token::RBrace);
20872097
}
20882098
else
2089-
ret.first = parseFunctionCallListArguments();
2099+
ret.arguments = parseFunctionCallListArguments();
20902100
return ret;
20912101
}
20922102

2093-
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseNamedArguments()
2103+
Parser::FunctionCallArguments Parser::parseNamedArguments()
20942104
{
2095-
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
2105+
FunctionCallArguments ret;
20962106

20972107
bool first = true;
20982108
while (m_scanner->currentToken() != Token::RBrace)
20992109
{
21002110
if (!first)
21012111
expectToken(Token::Comma);
21022112

2103-
ret.second.push_back(expectIdentifierToken());
2113+
auto identifierWithLocation = expectIdentifierWithLocation();
2114+
2115+
// Add name
2116+
ret.parameterNames.emplace_back(std::move(identifierWithLocation.first));
2117+
// Add location
2118+
ret.parameterNameLocations.emplace_back(std::move(identifierWithLocation.second));
2119+
21042120
expectToken(Token::Colon);
2105-
ret.first.push_back(parseExpression());
2121+
ret.arguments.emplace_back(parseExpression());
21062122

21072123
if (
21082124
m_scanner->currentToken() == Token::Comma &&

libsolidity/parsing/Parser.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ class Parser: public langutil::ParserBase
7777
std::vector<ASTPointer<ModifierInvocation>> modifiers;
7878
};
7979

80+
/// Struct to share parsed function call arguments.
81+
struct FunctionCallArguments
82+
{
83+
std::vector<ASTPointer<Expression>> arguments;
84+
std::vector<ASTPointer<ASTString>> parameterNames;
85+
std::vector<langutil::SourceLocation> parameterNameLocations;
86+
};
87+
8088
///@{
8189
///@name Parsing functions for the AST nodes
8290
void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);
@@ -153,8 +161,9 @@ class Parser: public langutil::ParserBase
153161
);
154162
ASTPointer<Expression> parsePrimaryExpression();
155163
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();
156-
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseFunctionCallArguments();
157-
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseNamedArguments();
164+
165+
FunctionCallArguments parseFunctionCallArguments();
166+
FunctionCallArguments parseNamedArguments();
158167
std::pair<ASTPointer<ASTString>, langutil::SourceLocation> expectIdentifierWithLocation();
159168
///@}
160169

test/libsolidity/ASTJSON/address_payable.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@
320320
"isPure": false,
321321
"kind": "typeConversion",
322322
"lValueRequested": false,
323+
"nameLocations": [],
323324
"names": [],
324325
"nodeType": "FunctionCall",
325326
"src": "209:13:1",
@@ -445,6 +446,7 @@
445446
"isPure": true,
446447
"kind": "typeConversion",
447448
"lValueRequested": false,
449+
"nameLocations": [],
448450
"names": [],
449451
"nodeType": "FunctionCall",
450452
"src": "239:10:1",

test/libsolidity/ASTJSON/address_payable_parseOnly.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@
210210
}
211211
},
212212
"id": 26,
213+
"nameLocations": [],
213214
"names": [],
214215
"nodeType": "FunctionCall",
215216
"src": "209:13:1",
@@ -281,6 +282,7 @@
281282
}
282283
},
283284
"id": 34,
285+
"nameLocations": [],
284286
"names": [],
285287
"nodeType": "FunctionCall",
286288
"src": "239:10:1",

test/libsolidity/ASTJSON/fail_after_parsing_parseOnly.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
"typeDescriptions": {}
150150
},
151151
"id": 18,
152+
"nameLocations": [],
152153
"names": [],
153154
"nodeType": "FunctionCall",
154155
"src": "117:3:1",

0 commit comments

Comments
 (0)