mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add location for parameter names in FunctionCall ASTNode
This commit is contained in:
parent
4d8a14b653
commit
3a5218d3d5
@ -2105,9 +2105,14 @@ public:
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<Expression> _expression,
|
||||
std::vector<ASTPointer<Expression>> _arguments,
|
||||
std::vector<ASTPointer<ASTString>> _names
|
||||
std::vector<ASTPointer<ASTString>> _names,
|
||||
std::vector<SourceLocation> _nameLocations
|
||||
):
|
||||
Expression(_id, _location), m_expression(std::move(_expression)), m_arguments(std::move(_arguments)), m_names(std::move(_names)) {}
|
||||
Expression(_id, _location), m_expression(std::move(_expression)), m_arguments(std::move(_arguments)), m_names(std::move(_names)), m_nameLocations(std::move(_nameLocations))
|
||||
{
|
||||
solAssert(m_nameLocations.size() == m_names.size());
|
||||
}
|
||||
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
@ -2120,6 +2125,7 @@ public:
|
||||
/// in the order they were written.
|
||||
/// If this is not a named call, this is empty.
|
||||
std::vector<ASTPointer<ASTString>> const& names() const { return m_names; }
|
||||
std::vector<SourceLocation> const& nameLocations() const { return m_nameLocations; }
|
||||
|
||||
FunctionCallAnnotation& annotation() const override;
|
||||
|
||||
@ -2127,6 +2133,7 @@ private:
|
||||
ASTPointer<Expression> m_expression;
|
||||
std::vector<ASTPointer<Expression>> m_arguments;
|
||||
std::vector<ASTPointer<ASTString>> m_names;
|
||||
std::vector<SourceLocation> m_nameLocations;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -128,6 +128,16 @@ string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location)
|
||||
return to_string(_location.start) + ":" + to_string(length) + ":" + (sourceIndexOpt.has_value() ? to_string(sourceIndexOpt.value()) : "-1");
|
||||
}
|
||||
|
||||
Json::Value ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const& _sourceLocations) const
|
||||
{
|
||||
Json::Value locations = Json::arrayValue;
|
||||
|
||||
for (SourceLocation const& location: _sourceLocations)
|
||||
locations.append(sourceLocationToString(location));
|
||||
|
||||
return locations;
|
||||
}
|
||||
|
||||
string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath)
|
||||
{
|
||||
return boost::algorithm::join(_namePath, ".");
|
||||
@ -843,6 +853,7 @@ bool ASTJsonExporter::visit(FunctionCall const& _node)
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("expression", toJson(_node.expression())),
|
||||
make_pair("names", std::move(names)),
|
||||
make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())),
|
||||
make_pair("arguments", toJson(_node.arguments())),
|
||||
make_pair("tryCall", _node.annotation().tryCall)
|
||||
};
|
||||
|
@ -144,6 +144,7 @@ private:
|
||||
/// Maps source location to an index, if source is valid and a mapping does exist, otherwise returns std::nullopt.
|
||||
std::optional<size_t> sourceIndexFromLocation(langutil::SourceLocation const& _location) const;
|
||||
std::string sourceLocationToString(langutil::SourceLocation const& _location) const;
|
||||
Json::Value sourceLocationsToJson(std::vector<langutil::SourceLocation> const& _sourceLocations) const;
|
||||
static std::string namePathToString(std::vector<ASTString> const& _namePath);
|
||||
static Json::Value idOrNull(ASTNode const* _pt)
|
||||
{
|
||||
|
@ -95,6 +95,20 @@ SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _n
|
||||
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
|
||||
}
|
||||
|
||||
optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const
|
||||
{
|
||||
vector<SourceLocation> locations;
|
||||
|
||||
if (_node.isMember("nameLocations") && _node["nameLocations"].isArray())
|
||||
{
|
||||
for (auto const& val: _node["nameLocations"])
|
||||
locations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames));
|
||||
return locations;
|
||||
}
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node)
|
||||
{
|
||||
astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string");
|
||||
@ -893,11 +907,17 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
|
||||
astAssert(name.isString(), "Expected 'names' members to be strings!");
|
||||
names.push_back(make_shared<ASTString>(name.asString()));
|
||||
}
|
||||
|
||||
optional<vector<SourceLocation>> sourceLocations = createSourceLocations(_node);
|
||||
|
||||
return createASTNode<FunctionCall>(
|
||||
_node,
|
||||
convertJsonToASTNode<Expression>(member(_node, "expression")),
|
||||
arguments,
|
||||
names
|
||||
names,
|
||||
sourceLocations ?
|
||||
*sourceLocations :
|
||||
vector<SourceLocation>(names.size())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@ private:
|
||||
ASTPointer<T> createASTNode(Json::Value const& _node, Args&&... _args);
|
||||
/// @returns the sourceLocation-object created from the string in the JSON node
|
||||
langutil::SourceLocation const createSourceLocation(Json::Value const& _node);
|
||||
std::optional<std::vector<langutil::SourceLocation>> createSourceLocations(Json::Value const& _node) const;
|
||||
/// Creates an ASTNode for a given JSON-ast of unknown type
|
||||
/// @returns Pointer to a new created ASTNode
|
||||
ASTPointer<ASTNode> convertJsonToASTNode(Json::Value const& _ast);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <cctype>
|
||||
#include <vector>
|
||||
#include <regex>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::langutil;
|
||||
@ -1542,13 +1543,16 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const
|
||||
auto eventName = expressionFromIndexAccessStructure(iap);
|
||||
expectToken(Token::LParen);
|
||||
|
||||
vector<ASTPointer<Expression>> arguments;
|
||||
vector<ASTPointer<ASTString>> names;
|
||||
std::tie(arguments, names) = parseFunctionCallArguments();
|
||||
auto functionCallArguments = parseFunctionCallArguments();
|
||||
eventCallNodeFactory.markEndPosition();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RParen);
|
||||
auto eventCall = eventCallNodeFactory.createNode<FunctionCall>(eventName, arguments, names);
|
||||
auto eventCall = eventCallNodeFactory.createNode<FunctionCall>(
|
||||
eventName,
|
||||
functionCallArguments.arguments,
|
||||
functionCallArguments.parameterNames,
|
||||
functionCallArguments.parameterNameLocations
|
||||
);
|
||||
return nodeFactory.createNode<EmitStatement>(_docString, eventCall);
|
||||
}
|
||||
|
||||
@ -1573,13 +1577,16 @@ ASTPointer<RevertStatement> Parser::parseRevertStatement(ASTPointer<ASTString> c
|
||||
auto errorName = expressionFromIndexAccessStructure(iap);
|
||||
expectToken(Token::LParen);
|
||||
|
||||
vector<ASTPointer<Expression>> arguments;
|
||||
vector<ASTPointer<ASTString>> names;
|
||||
std::tie(arguments, names) = parseFunctionCallArguments();
|
||||
auto functionCallArguments = parseFunctionCallArguments();
|
||||
errorCallNodeFactory.markEndPosition();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RParen);
|
||||
auto errorCall = errorCallNodeFactory.createNode<FunctionCall>(errorName, arguments, names);
|
||||
auto errorCall = errorCallNodeFactory.createNode<FunctionCall>(
|
||||
errorName,
|
||||
functionCallArguments.arguments,
|
||||
functionCallArguments.parameterNames,
|
||||
functionCallArguments.parameterNameLocations
|
||||
);
|
||||
return nodeFactory.createNode<RevertStatement>(_docString, errorCall);
|
||||
}
|
||||
|
||||
@ -1903,12 +1910,14 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
|
||||
case Token::LParen:
|
||||
{
|
||||
advance();
|
||||
vector<ASTPointer<Expression>> arguments;
|
||||
vector<ASTPointer<ASTString>> names;
|
||||
std::tie(arguments, names) = parseFunctionCallArguments();
|
||||
auto functionCallArguments = parseFunctionCallArguments();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RParen);
|
||||
expression = nodeFactory.createNode<FunctionCall>(expression, arguments, names);
|
||||
expression = nodeFactory.createNode<FunctionCall>(
|
||||
expression,
|
||||
functionCallArguments.arguments,
|
||||
functionCallArguments.parameterNames,
|
||||
functionCallArguments.parameterNameLocations);
|
||||
break;
|
||||
}
|
||||
case Token::LBrace:
|
||||
@ -1927,7 +1936,7 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RBrace);
|
||||
|
||||
expression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.first, optionList.second);
|
||||
expression = nodeFactory.createNode<FunctionCallOptions>(expression, optionList.arguments, optionList.parameterNames);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -2071,10 +2080,11 @@ vector<ASTPointer<Expression>> Parser::parseFunctionCallListArguments()
|
||||
return arguments;
|
||||
}
|
||||
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseFunctionCallArguments()
|
||||
Parser::FunctionCallArguments Parser::parseFunctionCallArguments()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
|
||||
FunctionCallArguments ret;
|
||||
|
||||
Token token = m_scanner->currentToken();
|
||||
if (token == Token::LBrace)
|
||||
{
|
||||
@ -2084,13 +2094,13 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
||||
expectToken(Token::RBrace);
|
||||
}
|
||||
else
|
||||
ret.first = parseFunctionCallListArguments();
|
||||
ret.arguments = parseFunctionCallListArguments();
|
||||
return ret;
|
||||
}
|
||||
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::parseNamedArguments()
|
||||
Parser::FunctionCallArguments Parser::parseNamedArguments()
|
||||
{
|
||||
pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> ret;
|
||||
FunctionCallArguments ret;
|
||||
|
||||
bool first = true;
|
||||
while (m_scanner->currentToken() != Token::RBrace)
|
||||
@ -2098,9 +2108,15 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
||||
if (!first)
|
||||
expectToken(Token::Comma);
|
||||
|
||||
ret.second.push_back(expectIdentifierToken());
|
||||
auto identifierWithLocation = expectIdentifierWithLocation();
|
||||
|
||||
// Add name
|
||||
ret.parameterNames.emplace_back(std::move(identifierWithLocation.first));
|
||||
// Add location
|
||||
ret.parameterNameLocations.emplace_back(std::move(identifierWithLocation.second));
|
||||
|
||||
expectToken(Token::Colon);
|
||||
ret.first.push_back(parseExpression());
|
||||
ret.arguments.emplace_back(parseExpression());
|
||||
|
||||
if (
|
||||
m_scanner->currentToken() == Token::Comma &&
|
||||
|
@ -77,6 +77,14 @@ private:
|
||||
std::vector<ASTPointer<ModifierInvocation>> modifiers;
|
||||
};
|
||||
|
||||
/// Struct to share parsed function call arguments.
|
||||
struct FunctionCallArguments
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
std::vector<ASTPointer<ASTString>> parameterNames;
|
||||
std::vector<langutil::SourceLocation> parameterNameLocations;
|
||||
};
|
||||
|
||||
///@{
|
||||
///@name Parsing functions for the AST nodes
|
||||
void parsePragmaVersion(langutil::SourceLocation const& _location, std::vector<Token> const& _tokens, std::vector<std::string> const& _literals);
|
||||
@ -153,8 +161,9 @@ private:
|
||||
);
|
||||
ASTPointer<Expression> parsePrimaryExpression();
|
||||
std::vector<ASTPointer<Expression>> parseFunctionCallListArguments();
|
||||
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseFunctionCallArguments();
|
||||
std::pair<std::vector<ASTPointer<Expression>>, std::vector<ASTPointer<ASTString>>> parseNamedArguments();
|
||||
|
||||
FunctionCallArguments parseFunctionCallArguments();
|
||||
FunctionCallArguments parseNamedArguments();
|
||||
std::pair<ASTPointer<ASTString>, langutil::SourceLocation> expectIdentifierWithLocation();
|
||||
///@}
|
||||
|
||||
|
@ -320,6 +320,7 @@
|
||||
"isPure": false,
|
||||
"kind": "typeConversion",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "209:13:1",
|
||||
@ -445,6 +446,7 @@
|
||||
"isPure": true,
|
||||
"kind": "typeConversion",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "239:10:1",
|
||||
|
@ -210,6 +210,7 @@
|
||||
}
|
||||
},
|
||||
"id": 26,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "209:13:1",
|
||||
@ -281,6 +282,7 @@
|
||||
}
|
||||
},
|
||||
"id": 34,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "239:10:1",
|
||||
|
@ -149,6 +149,7 @@
|
||||
"typeDescriptions": {}
|
||||
},
|
||||
"id": 18,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "117:3:1",
|
||||
|
@ -135,6 +135,7 @@
|
||||
"isPure": true,
|
||||
"kind": "typeConversion",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "60:14:1",
|
||||
@ -182,6 +183,7 @@
|
||||
"isPure": true,
|
||||
"kind": "typeConversion",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "53:22:1",
|
||||
|
@ -85,6 +85,7 @@
|
||||
}
|
||||
},
|
||||
"id": 10,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "60:14:1",
|
||||
@ -108,6 +109,7 @@
|
||||
}
|
||||
},
|
||||
"id": 11,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "53:22:1",
|
||||
|
@ -67,6 +67,7 @@
|
||||
"isPure": false,
|
||||
"kind": "functionCall",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "38:3:1",
|
||||
@ -175,6 +176,7 @@
|
||||
"isPure": false,
|
||||
"kind": "functionCall",
|
||||
"lValueRequested": false,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "99:3:1",
|
||||
|
@ -40,6 +40,7 @@
|
||||
"typeDescriptions": {}
|
||||
},
|
||||
"id": 6,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "38:3:1",
|
||||
@ -125,6 +126,7 @@
|
||||
"typeDescriptions": {}
|
||||
},
|
||||
"id": 15,
|
||||
"nameLocations": [],
|
||||
"names": [],
|
||||
"nodeType": "FunctionCall",
|
||||
"src": "99:3:1",
|
||||
|
Loading…
Reference in New Issue
Block a user