mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add AST Node IdentifierPath
This commit is contained in:
@@ -219,7 +219,7 @@ struct OverrideSpecifierChecker: public PostTypeChecker::Checker
|
||||
{
|
||||
for (ASTPointer<UserDefinedTypeName> const& override: _overrideSpecifier.overrides())
|
||||
{
|
||||
Declaration const* decl = override->annotation().referencedDeclaration;
|
||||
Declaration const* decl = override->annotation().referencedDeclaration;
|
||||
solAssert(decl, "Expected declaration to be resolved.");
|
||||
|
||||
if (dynamic_cast<ContractDefinition const*>(decl))
|
||||
|
||||
@@ -171,16 +171,21 @@ void ReferencesResolver::endVisit(ModifierDefinition const&)
|
||||
m_returnParameters.pop_back();
|
||||
}
|
||||
|
||||
void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
|
||||
void ReferencesResolver::endVisit(IdentifierPath const& _path)
|
||||
{
|
||||
Declaration const* declaration = m_resolver.pathFromCurrentScope(_typeName.namePath());
|
||||
Declaration const* declaration = m_resolver.pathFromCurrentScope(_path.path());
|
||||
if (!declaration)
|
||||
{
|
||||
m_errorReporter.fatalDeclarationError(7920_error, _typeName.location(), "Identifier not found or not unique.");
|
||||
m_errorReporter.fatalDeclarationError(7920_error, _path.location(), "Identifier not found or not unique.");
|
||||
return;
|
||||
}
|
||||
|
||||
_typeName.annotation().referencedDeclaration = declaration;
|
||||
_path.annotation().referencedDeclaration = declaration;
|
||||
}
|
||||
|
||||
void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName)
|
||||
{
|
||||
_typeName.annotation().referencedDeclaration = _typeName.pathNode()->annotation().referencedDeclaration;
|
||||
}
|
||||
|
||||
bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
|
||||
|
||||
@@ -82,6 +82,7 @@ private:
|
||||
void endVisit(FunctionDefinition const& _functionDefinition) override;
|
||||
bool visit(ModifierDefinition const& _modifierDefinition) override;
|
||||
void endVisit(ModifierDefinition const& _modifierDefinition) override;
|
||||
void endVisit(IdentifierPath const& _typeName) override;
|
||||
void endVisit(UserDefinedTypeName const& _typeName) override;
|
||||
bool visit(InlineAssembly const& _inlineAssembly) override;
|
||||
bool visit(Return const& _return) override;
|
||||
|
||||
+25
-3
@@ -557,6 +557,27 @@ private:
|
||||
util::LazyInit<std::vector<EventDefinition const*>> m_interfaceEvents;
|
||||
};
|
||||
|
||||
/**
|
||||
* A sequence of identifiers separated by dots
|
||||
*/
|
||||
class IdentifierPath: public ASTNode
|
||||
{
|
||||
public:
|
||||
IdentifierPath(int64_t _id, SourceLocation const& _location, std::vector<ASTString> _path):
|
||||
ASTNode(_id, _location), m_path(std::move(_path)) {}
|
||||
|
||||
std::vector<ASTString> const& path() const { return m_path; }
|
||||
IdentifierPathAnnotation& annotation() const override
|
||||
{
|
||||
return initAnnotation<IdentifierPathAnnotation>();
|
||||
}
|
||||
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
private:
|
||||
std::vector<ASTString> m_path;
|
||||
};
|
||||
|
||||
class InheritanceSpecifier: public ASTNode
|
||||
{
|
||||
public:
|
||||
@@ -1203,18 +1224,19 @@ private:
|
||||
class UserDefinedTypeName: public TypeName
|
||||
{
|
||||
public:
|
||||
UserDefinedTypeName(int64_t _id, SourceLocation const& _location, std::vector<ASTString> _namePath):
|
||||
UserDefinedTypeName(int64_t _id, SourceLocation const& _location, ASTPointer<IdentifierPath> _namePath):
|
||||
TypeName(_id, _location), m_namePath(std::move(_namePath)) {}
|
||||
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
std::vector<ASTString> const& namePath() const { return m_namePath; }
|
||||
std::vector<ASTString> const& namePath() const { return m_namePath->path(); }
|
||||
ASTPointer<IdentifierPath> const& pathNode() const { return m_namePath; }
|
||||
|
||||
UserDefinedTypeNameAnnotation& annotation() const override;
|
||||
|
||||
private:
|
||||
std::vector<ASTString> m_namePath;
|
||||
ASTPointer<IdentifierPath> m_namePath;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -233,6 +233,12 @@ struct TypeNameAnnotation: ASTAnnotation
|
||||
TypePointer type = nullptr;
|
||||
};
|
||||
|
||||
struct IdentifierPathAnnotation: TypeNameAnnotation
|
||||
{
|
||||
/// Referenced declaration, set during reference resolution stage.
|
||||
Declaration const* referencedDeclaration = nullptr;
|
||||
};
|
||||
|
||||
struct UserDefinedTypeNameAnnotation: TypeNameAnnotation
|
||||
{
|
||||
/// Referenced declaration, set during reference resolution stage.
|
||||
|
||||
@@ -326,6 +326,15 @@ bool ASTJsonConverter::visit(ContractDefinition const& _node)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASTJsonConverter::visit(IdentifierPath const& _node)
|
||||
{
|
||||
setJsonNode(_node, "IdentifierPath", {
|
||||
make_pair("name", namePathToString(_node.path())),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration))
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASTJsonConverter::visit(InheritanceSpecifier const& _node)
|
||||
{
|
||||
setJsonNode(_node, "InheritanceSpecifier", {
|
||||
@@ -519,7 +528,7 @@ bool ASTJsonConverter::visit(ElementaryTypeName const& _node)
|
||||
bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
|
||||
{
|
||||
setJsonNode(_node, "UserDefinedTypeName", {
|
||||
make_pair("name", namePathToString(_node.namePath())),
|
||||
make_pair("pathNode", toJson(*_node.pathNode())),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
|
||||
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
|
||||
});
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
bool visit(PragmaDirective const& _node) override;
|
||||
bool visit(ImportDirective const& _node) override;
|
||||
bool visit(ContractDefinition const& _node) override;
|
||||
bool visit(IdentifierPath const& _node) override;
|
||||
bool visit(InheritanceSpecifier const& _node) override;
|
||||
bool visit(UsingForDirective const& _node) override;
|
||||
bool visit(StructDefinition const& _node) override;
|
||||
|
||||
@@ -115,6 +115,8 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
|
||||
return createImportDirective(_json);
|
||||
if (nodeType == "ContractDefinition")
|
||||
return createContractDefinition(_json);
|
||||
if (nodeType == "IdentifierPath")
|
||||
return createIdentifier(_json);
|
||||
if (nodeType == "InheritanceSpecifier")
|
||||
return createInheritanceSpecifier(_json);
|
||||
if (nodeType == "UsingForDirective")
|
||||
@@ -299,6 +301,22 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json::V
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value const& _node)
|
||||
{
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
|
||||
vector<ASTString> namePath;
|
||||
vector<string> strs;
|
||||
string nameString = member(_node, "name").asString();
|
||||
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
|
||||
for (string s: strs)
|
||||
namePath.emplace_back(s);
|
||||
return createASTNode<IdentifierPath>(
|
||||
_node,
|
||||
namePath
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json::Value const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
@@ -518,17 +536,9 @@ ASTPointer<ElementaryTypeName> ASTJsonImporter::createElementaryTypeName(Json::V
|
||||
|
||||
ASTPointer<UserDefinedTypeName> ASTJsonImporter::createUserDefinedTypeName(Json::Value const& _node)
|
||||
{
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
|
||||
vector<ASTString> namePath;
|
||||
vector<string> strs;
|
||||
string nameString = member(_node, "name").asString();
|
||||
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
|
||||
for (string s: strs)
|
||||
namePath.emplace_back(s);
|
||||
return createASTNode<UserDefinedTypeName>(
|
||||
_node,
|
||||
namePath
|
||||
createIdentifierPath(member(_node, "pathNode"))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ private:
|
||||
ASTPointer<PragmaDirective> createPragmaDirective(Json::Value const& _node);
|
||||
ASTPointer<ImportDirective> createImportDirective(Json::Value const& _node);
|
||||
ASTPointer<ContractDefinition> createContractDefinition(Json::Value const& _node);
|
||||
ASTPointer<IdentifierPath> createIdentifierPath(Json::Value const& _node);
|
||||
ASTPointer<InheritanceSpecifier> createInheritanceSpecifier(Json::Value const& _node);
|
||||
ASTPointer<UsingForDirective> createUsingForDirective(Json::Value const& _node);
|
||||
ASTPointer<ASTNode> createStructDefinition(Json::Value const& _node);
|
||||
|
||||
@@ -58,6 +58,7 @@ public:
|
||||
virtual bool visit(PragmaDirective& _node) { return visitNode(_node); }
|
||||
virtual bool visit(ImportDirective& _node) { return visitNode(_node); }
|
||||
virtual bool visit(ContractDefinition& _node) { return visitNode(_node); }
|
||||
virtual bool visit(IdentifierPath& _node) { return visitNode(_node); }
|
||||
virtual bool visit(InheritanceSpecifier& _node) { return visitNode(_node); }
|
||||
virtual bool visit(UsingForDirective& _node) { return visitNode(_node); }
|
||||
virtual bool visit(StructDefinition& _node) { return visitNode(_node); }
|
||||
@@ -110,6 +111,7 @@ public:
|
||||
virtual void endVisit(PragmaDirective& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(ImportDirective& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(ContractDefinition& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(IdentifierPath& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(InheritanceSpecifier& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(UsingForDirective& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(StructDefinition& _node) { endVisitNode(_node); }
|
||||
@@ -184,6 +186,7 @@ public:
|
||||
virtual bool visit(PragmaDirective const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(ImportDirective const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(ContractDefinition const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(IdentifierPath const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(InheritanceSpecifier const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(StructDefinition const& _node) { return visitNode(_node); }
|
||||
virtual bool visit(UsingForDirective const& _node) { return visitNode(_node); }
|
||||
@@ -236,6 +239,7 @@ public:
|
||||
virtual void endVisit(PragmaDirective const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(ImportDirective const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(ContractDefinition const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(IdentifierPath const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(InheritanceSpecifier const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(UsingForDirective const& _node) { endVisitNode(_node); }
|
||||
virtual void endVisit(StructDefinition const& _node) { endVisitNode(_node); }
|
||||
|
||||
@@ -104,6 +104,18 @@ void ContractDefinition::accept(ASTConstVisitor& _visitor) const
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IdentifierPath::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IdentifierPath::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void InheritanceSpecifier::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
@@ -368,13 +380,15 @@ void ElementaryTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
|
||||
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
if (_visitor.visit(*this))
|
||||
this->pathNode()->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
if (_visitor.visit(*this))
|
||||
this->pathNode()->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -939,6 +939,14 @@ ASTPointer<Identifier> Parser::parseIdentifier()
|
||||
}
|
||||
|
||||
ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ASTPointer<IdentifierPath> identifierPath = parseIdentifierPath();
|
||||
nodeFactory.setEndPositionFromNode(identifierPath);
|
||||
return nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
|
||||
}
|
||||
|
||||
ASTPointer<IdentifierPath> Parser::parseIdentifierPath()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
@@ -950,7 +958,7 @@ ASTPointer<UserDefinedTypeName> Parser::parseUserDefinedTypeName()
|
||||
nodeFactory.markEndPosition();
|
||||
identifierPath.push_back(*expectIdentifierToken());
|
||||
}
|
||||
return nodeFactory.createNode<UserDefinedTypeName>(identifierPath);
|
||||
return nodeFactory.createNode<IdentifierPath>(identifierPath);
|
||||
}
|
||||
|
||||
ASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory)
|
||||
@@ -2101,7 +2109,7 @@ ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAcces
|
||||
vector<ASTString> path;
|
||||
for (auto const& el: _iap.path)
|
||||
path.push_back(dynamic_cast<Identifier const&>(*el).name());
|
||||
type = nodeFactory.createNode<UserDefinedTypeName>(path);
|
||||
type = nodeFactory.createNode<UserDefinedTypeName>(nodeFactory.createNode<IdentifierPath>(path));
|
||||
}
|
||||
for (auto const& lengthExpression: _iap.indices)
|
||||
{
|
||||
|
||||
@@ -106,6 +106,7 @@ private:
|
||||
ASTPointer<ModifierInvocation> parseModifierInvocation();
|
||||
ASTPointer<Identifier> parseIdentifier();
|
||||
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
|
||||
ASTPointer<IdentifierPath> parseIdentifierPath();
|
||||
ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
|
||||
ASTPointer<TypeName> parseTypeName();
|
||||
ASTPointer<FunctionTypeName> parseFunctionType();
|
||||
|
||||
Reference in New Issue
Block a user