Skip to content

Commit

Permalink
AST Json import/export
Browse files Browse the repository at this point in the history
  • Loading branch information
matheusaaguiar committed Jan 24, 2025
1 parent b776c85 commit 7a42733
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 35 deletions.
4 changes: 2 additions & 2 deletions libsolidity/ast/AST.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ class ContractDefinition: public Declaration, public StructurallyDocumented, pub

bool abstract() const { return m_abstract; }

ASTPointer<StorageBaseLocation> storageBaseLocation() { return m_storageBaseLocation; }
ASTPointer<StorageBaseLocation> storageBaseLocation() const { return m_storageBaseLocation; }

ContractDefinition const* superContract(ContractDefinition const& _mostDerivedContract) const;
/// @returns the next constructor in the inheritance hierarchy.
Expand Down Expand Up @@ -623,7 +623,7 @@ class StorageBaseLocation : public ASTNode
void accept(ASTVisitor& _visitor) override;
void accept(ASTConstVisitor& _visitor) const override;

ASTPointer<Expression> expression() { return m_expression; }
ASTPointer<Expression> expression() const { return m_expression; }
private:
ASTPointer<Expression> m_expression;
};
Expand Down
11 changes: 10 additions & 1 deletion libsolidity/ast/ASTJsonExporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ bool ASTJsonExporter::visit(ImportDirective const& _node)
return false;
}

bool ASTJsonExporter::visit(StorageBaseLocation const& _node)
{
std::vector<std::pair<std::string, Json>> attributes = {
std::make_pair("expression", toJson(*_node.expression()))
};
setJsonNode(_node, "StorageBaseLocation", std::move(attributes));
return false;
}

bool ASTJsonExporter::visit(ContractDefinition const& _node)
{
std::vector<std::pair<std::string, Json>> attributes = {
Expand All @@ -294,7 +303,7 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node)
std::make_pair("usedErrors", getContainerIds(_node.interfaceErrors(false))),
std::make_pair("nodes", toJson(_node.subNodes())),
std::make_pair("scope", idOrNull(_node.scope())),
std::make_pair("storageBaseLocation", idOrNull(_node.storageBaseLocationExpression().get()))
std::make_pair("storageBaseLocation", _node.storageBaseLocation() ? toJson(*_node.storageBaseLocation()) : Json())
};
addIfSet(attributes, "canonicalName", _node.annotation().canonicalName);

Expand Down
1 change: 1 addition & 0 deletions libsolidity/ast/ASTJsonExporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class ASTJsonExporter: public ASTConstVisitor
bool visit(ElementaryTypeNameExpression const& _node) override;
bool visit(Literal const& _node) override;
bool visit(StructuredDocumentation const& _node) override;
bool visit(StorageBaseLocation const& _node) override;

void endVisit(EventDefinition const&) override;

Expand Down
37 changes: 9 additions & 28 deletions libsolidity/ast/ASTJsonImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json const& _json)
return createLiteral(_json);
if (nodeType == "StructuredDocumentation")
return createDocumentation(_json);
if (nodeType == "StorageBaseLocation")
return createStorageBaseLocation(_json);
else
astAssert(false, "Unknown type of ASTNode: " + nodeType);

Expand Down Expand Up @@ -344,8 +346,6 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json co
for (auto& subnode: _node["nodes"])
subNodes.push_back(convertJsonToASTNode(subnode));

ASTPointer<ASTNode> storageBaseLocation = contractStorageBaseLocation(_node, subNodes);

return createASTNode<ContractDefinition>(
_node,
std::make_shared<ASTString>(_node["name"].get<std::string>()),
Expand All @@ -355,20 +355,17 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json co
subNodes,
contractKind(_node),
memberAsBool(_node, "abstract"),
storageBaseLocation
nullOrCast<StorageBaseLocation>(member(_node, "storageBaseLocation"))
);
}

ASTPointer<Expression> ASTJsonImporter::contractStorageBaseLocation(Json const& _node, std::vector<ASTPointer<ASTNode>> _subNodes)
ASTPointer<StorageBaseLocation> ASTJsonImporter::createStorageBaseLocation(Json const& _node)
{
astAssert(_node.contains("nodes"));
if (_node.contains("storageBaseLocation"))
if (
ASTPointer<ASTNode> subNode = ranges::find_if(_subNodes, [&](ASTPointer<ASTNode> _sub) { return _sub->id() == memberAsInteger(_node, "storageBaseLocation"); } );
subNode != ranges::end(_subNodes)
)
return *subNode;
return nullptr;
astAssert(_node.contains("expression"));
return createASTNode<StorageBaseLocation>(
_node,
std::dynamic_pointer_cast<Expression>(convertJsonToASTNode(_node["expression"]))
);
}

ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json const& _node)
Expand Down Expand Up @@ -1117,15 +1114,6 @@ Json ASTJsonImporter::member(Json const& _node, std::string const& _name)
return _node[_name];
}

Json ASTJsonImporter::nodeFromArray(Json const& _array, int64_t const _id)
{
astAssert(_array.is_array(), "node must be an array");
for (auto& node: _array)
if (node.contains("id") && memberAsInteger(node, "id") == _id)
return node;
return Json();
}

Token ASTJsonImporter::scanSingleToken(Json const& _node)
{
langutil::CharStream charStream(_node.get<std::string>(), "");
Expand Down Expand Up @@ -1153,13 +1141,6 @@ bool ASTJsonImporter::memberAsBool(Json const& _node, std::string const& _name)
return _node[_name].get<bool>();
}

int64_t ASTJsonImporter::memberAsInteger(Json const& _node, std::string const& _name)
{
Json value = member(_node, _name);
astAssert(value.is_number(), "field " + _name + " must be of type integer.");
return _node[_name].get<int64_t>();
}


// =========== JSON to definition helpers =======================

Expand Down
5 changes: 1 addition & 4 deletions libsolidity/ast/ASTJsonImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,12 @@ class ASTJsonImporter
ASTPointer<ElementaryTypeNameExpression> createElementaryTypeNameExpression(Json const& _node);
ASTPointer<ASTNode> createLiteral(Json const& _node);
ASTPointer<StructuredDocumentation> createDocumentation(Json const& _node);
ASTPointer<StorageBaseLocation> createStorageBaseLocation(Json const& _node);
///@}

// =============== general helper functions ===================
/// @returns the member of a given JSON object or null if member does not exist
Json member(Json const& _node, std::string const& _name);
/// @returns the object with given ID from a given JSON array or null if it does not exist
Json nodeFromArray(Json const& _array, int64_t const _id);
/// @returns the appropriate TokenObject used in parsed Strings (pragma directive or operator)
Token scanSingleToken(Json const& _node);
template<class T>
Expand All @@ -151,14 +150,12 @@ class ASTJsonImporter
/// {@
ASTPointer<ASTString> memberAsASTString(Json const& _node, std::string const& _name);
bool memberAsBool(Json const& _node, std::string const& _name);
int64_t memberAsInteger(Json const& _node, std::string const& _name);
Visibility visibility(Json const& _node);
StateMutability stateMutability(Json const& _node);
VariableDeclaration::Location location(Json const& _node);
ContractKind contractKind(Json const& _node);
Token literalTokenKind(Json const& _node);
Literal::SubDenomination subdenomination(Json const& _node);
ASTPointer<Expression> contractStorageBaseLocation(Json const& _node, std::vector<ASTPointer<ASTNode>> _subNodes);
///@}

// =========== member variables ===============
Expand Down

0 comments on commit 7a42733

Please sign in to comment.