Allow path syntax for super constructor calls

This commit is contained in:
Mathias Baumann
2020-10-13 14:32:11 +02:00
parent 0b7b174945
commit 006e5f2e1f
57 changed files with 579 additions and 893 deletions
-5
View File
@@ -460,11 +460,6 @@ EventDefinitionAnnotation& EventDefinition::annotation() const
return initAnnotation<EventDefinitionAnnotation>();
}
UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const
{
return initAnnotation<UserDefinedTypeNameAnnotation>();
}
SourceUnit const& Scopable::sourceUnit() const
{
ASTNode const* s = scope();
+18 -18
View File
@@ -558,7 +558,7 @@ private:
};
/**
* A sequence of identifiers separated by dots
* A sequence of identifiers separated by dots used outside the expression context. Inside the expression context, this is a sequence of Identifier and MemberAccess.
*/
class IdentifierPath: public ASTNode
{
@@ -584,7 +584,7 @@ public:
InheritanceSpecifier(
int64_t _id,
SourceLocation const& _location,
ASTPointer<UserDefinedTypeName> _baseName,
ASTPointer<IdentifierPath> _baseName,
std::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments
):
ASTNode(_id, _location), m_baseName(std::move(_baseName)), m_arguments(std::move(_arguments))
@@ -595,14 +595,14 @@ public:
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
UserDefinedTypeName const& name() const { return *m_baseName; }
IdentifierPath const& name() const { return *m_baseName; }
// Returns nullptr if no argument list was given (``C``).
// If an argument list is given (``C(...)``), the arguments are returned
// as a vector of expressions. Note that this vector can be empty (``C()``).
std::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }
private:
ASTPointer<UserDefinedTypeName> m_baseName;
ASTPointer<IdentifierPath> m_baseName;
std::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;
};
@@ -617,7 +617,7 @@ public:
UsingForDirective(
int64_t _id,
SourceLocation const& _location,
ASTPointer<UserDefinedTypeName> _libraryName,
ASTPointer<IdentifierPath> _libraryName,
ASTPointer<TypeName> _typeName
):
ASTNode(_id, _location), m_libraryName(std::move(_libraryName)), m_typeName(std::move(_typeName))
@@ -628,12 +628,12 @@ public:
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
UserDefinedTypeName const& libraryName() const { return *m_libraryName; }
IdentifierPath const& libraryName() const { return *m_libraryName; }
/// @returns the type name the library is attached to, null for `*`.
TypeName const* typeName() const { return m_typeName.get(); }
private:
ASTPointer<UserDefinedTypeName> m_libraryName;
ASTPointer<IdentifierPath> m_libraryName;
ASTPointer<TypeName> m_typeName;
};
@@ -792,7 +792,7 @@ public:
OverrideSpecifier(
int64_t _id,
SourceLocation const& _location,
std::vector<ASTPointer<UserDefinedTypeName>> _overrides
std::vector<ASTPointer<IdentifierPath>> _overrides
):
ASTNode(_id, _location),
m_overrides(std::move(_overrides))
@@ -803,10 +803,10 @@ public:
void accept(ASTConstVisitor& _visitor) const override;
/// @returns the list of specific overrides, if any
std::vector<ASTPointer<UserDefinedTypeName>> const& overrides() const { return m_overrides; }
std::vector<ASTPointer<IdentifierPath>> const& overrides() const { return m_overrides; }
protected:
std::vector<ASTPointer<UserDefinedTypeName>> m_overrides;
std::vector<ASTPointer<IdentifierPath>> m_overrides;
};
class FunctionDefinition: public CallableDeclaration, public StructurallyDocumented, public ImplementationOptional, public ScopeOpener
@@ -1077,7 +1077,7 @@ public:
ModifierInvocation(
int64_t _id,
SourceLocation const& _location,
ASTPointer<Identifier> _name,
ASTPointer<IdentifierPath> _name,
std::unique_ptr<std::vector<ASTPointer<Expression>>> _arguments
):
ASTNode(_id, _location), m_modifierName(std::move(_name)), m_arguments(std::move(_arguments))
@@ -1088,14 +1088,14 @@ public:
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
ASTPointer<Identifier> const& name() const { return m_modifierName; }
IdentifierPath& name() const { return *m_modifierName; }
// Returns nullptr if no argument list was given (``mod``).
// If an argument list is given (``mod(...)``), the arguments are returned
// as a vector of expressions. Note that this vector can be empty (``mod()``).
std::vector<ASTPointer<Expression>> const* arguments() const { return m_arguments.get(); }
private:
ASTPointer<Identifier> m_modifierName;
ASTPointer<IdentifierPath> m_modifierName;
std::unique_ptr<std::vector<ASTPointer<Expression>>> m_arguments;
};
@@ -1225,15 +1225,15 @@ class UserDefinedTypeName: public TypeName
{
public:
UserDefinedTypeName(int64_t _id, SourceLocation const& _location, ASTPointer<IdentifierPath> _namePath):
TypeName(_id, _location), m_namePath(std::move(_namePath)) {}
TypeName(_id, _location), m_namePath(std::move(_namePath))
{
solAssert(m_namePath != nullptr, "Name cannot be null.");
}
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;
std::vector<ASTString> const& namePath() const { return m_namePath->path(); }
ASTPointer<IdentifierPath> const& pathNode() const { return m_namePath; }
UserDefinedTypeNameAnnotation& annotation() const override;
IdentifierPath& pathNode() const { return *m_namePath; }
private:
ASTPointer<IdentifierPath> m_namePath;
+3 -7
View File
@@ -233,16 +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
struct IdentifierPathAnnotation: ASTAnnotation
{
/// Referenced declaration, set during reference resolution stage.
Declaration const* referencedDeclaration = nullptr;
/// What kind of lookup needs to be done (static, virtual, super) find the declaration.
SetOnce<VirtualLookup> requiredLookup;
};
struct ExpressionAnnotation: ASTAnnotation
+3 -3
View File
@@ -493,7 +493,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node)
bool ASTJsonConverter::visit(ModifierInvocation const& _node)
{
setJsonNode(_node, "ModifierInvocation", {
make_pair("modifierName", toJson(*_node.name())),
make_pair("modifierName", toJson(_node.name())),
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
});
return false;
@@ -528,8 +528,8 @@ bool ASTJsonConverter::visit(ElementaryTypeName const& _node)
bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
{
setJsonNode(_node, "UserDefinedTypeName", {
make_pair("pathNode", toJson(*_node.pathNode())),
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
make_pair("pathNode", toJson(_node.pathNode())),
make_pair("referencedDeclaration", idOrNull(_node.pathNode().annotation().referencedDeclaration)),
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
});
return false;
+11 -10
View File
@@ -116,7 +116,7 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
if (nodeType == "ContractDefinition")
return createContractDefinition(_json);
if (nodeType == "IdentifierPath")
return createIdentifier(_json);
return createIdentifierPath(_json);
if (nodeType == "InheritanceSpecifier")
return createInheritanceSpecifier(_json);
if (nodeType == "UsingForDirective")
@@ -309,12 +309,13 @@ ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value con
vector<string> strs;
string nameString = member(_node, "name").asString();
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
astAssert(!strs.empty(), "Expected at least one element in IdentifierPath.");
for (string s: strs)
{
astAssert(!s.empty(), "Expected non-empty string for IdentifierPath element.");
namePath.emplace_back(s);
return createASTNode<IdentifierPath>(
_node,
namePath
);
}
return createASTNode<IdentifierPath>(_node, namePath);
}
ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json::Value const& _node)
@@ -324,7 +325,7 @@ ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Jso
arguments.push_back(convertJsonToASTNode<Expression>(arg));
return createASTNode<InheritanceSpecifier>(
_node,
createUserDefinedTypeName(member(_node, "baseName")),
createIdentifierPath(member(_node, "baseName")),
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
);
}
@@ -333,7 +334,7 @@ ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Val
{
return createASTNode<UsingForDirective>(
_node,
createUserDefinedTypeName(member(_node, "libraryName")),
createIdentifierPath(member(_node, "libraryName")),
_node["typeName"].isNull() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"])
);
}
@@ -383,10 +384,10 @@ ASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json::Value const
ASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json::Value const& _node)
{
std::vector<ASTPointer<UserDefinedTypeName>> overrides;
std::vector<ASTPointer<IdentifierPath>> overrides;
for (auto& param: _node["overrides"])
overrides.push_back(createUserDefinedTypeName(param));
overrides.push_back(createIdentifierPath(param));
return createASTNode<OverrideSpecifier>(
_node,
@@ -499,7 +500,7 @@ ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json::V
arguments.push_back(convertJsonToASTNode<Expression>(arg));
return createASTNode<ModifierInvocation>(
_node,
createIdentifier(member(_node, "modifierName")),
createIdentifierPath(member(_node, "modifierName")),
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
);
}
+2 -2
View File
@@ -381,14 +381,14 @@ void ElementaryTypeName::accept(ASTConstVisitor& _visitor) const
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
this->pathNode()->accept(_visitor);
this->pathNode().accept(_visitor);
_visitor.endVisit(*this);
}
void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
{
if (_visitor.visit(*this))
this->pathNode()->accept(_visitor);
this->pathNode().accept(_visitor);
_visitor.endVisit(*this);
}