Add AST Node IdentifierPath

This commit is contained in:
Mathias Baumann
2020-10-13 14:32:11 +02:00
parent 0ea4bdafcd
commit 0b7b174945
33 changed files with 797 additions and 392 deletions
+1 -1
View File
@@ -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))
+9 -4
View File
@@ -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
View File
@@ -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;
};
/**
+6
View File
@@ -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.
+10 -1
View File
@@ -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))
});
+1
View File
@@ -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;
+19 -9
View File
@@ -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"))
);
}
+1
View File
@@ -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);
+4
View File
@@ -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); }
+16 -2
View File
@@ -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);
}
+10 -2
View File
@@ -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)
{
+1
View File
@@ -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();