// Copyright (c) 2020-now by the Zeek Project. See LICENSE for details. #pragma once #include #include #include #include #include #include #include namespace hilti::ctor { namespace map { /** Base class for map field nodes. */ class Element final : public Node { public: ~Element() final; auto key() const { return child(0); } auto value() const { return child(1); } static auto create(ASTContext* ctx, Expression* key, Expression* value, Meta meta = {}) { return ctx->make(ctx, {key, value}, std::move(meta)); } protected: Element(ASTContext* ctx, Nodes children, Meta meta = {}) : Node(ctx, NodeTags, std::move(children), std::move(meta)) {} std::string _dump() const final; HILTI_NODE_0(ctor::map::Element, final); }; using Elements = NodeVector; } // namespace map /** AST node for a `map` ctor. */ class Map : public Ctor { public: auto value() const { return children(1, {}); } auto keyType() const { if ( auto mtype = type()->type()->tryAs() ) return mtype->keyType(); else return type(); // auto } auto valueType() const { if ( auto mtype = type()->type()->tryAs() ) return mtype->valueType(); else return type(); // auto } QualifiedType* type() const final { return child(0); } void setType(ASTContext* ctx, QualifiedType* type) { setChild(ctx, 0, type); } void setValue(ASTContext* ctx, const map::Elements& exprs) { removeChildren(1, {}); addChildren(ctx, exprs); } static auto create(ASTContext* ctx, QualifiedType* key, QualifiedType* value, const map::Elements& elements, Meta meta = {}) { auto mtype = QualifiedType::create(ctx, type::Map::create(ctx, key, value, meta), Constness::Mutable, meta); return ctx->make(ctx, node::flatten(mtype, elements), std::move(meta)); } static auto create(ASTContext* ctx, const map::Elements& elements, Meta meta = {}) { // bool is just an arbitrary place-holder type for empty values. auto mtype = elements.empty() ? QualifiedType::create(ctx, type::Bool::create(ctx, meta), Constness::Mutable, meta) : QualifiedType::createAuto(ctx, meta); return ctx->make(ctx, node::flatten(mtype, elements), std::move(meta)); } protected: Map(ASTContext* ctx, Nodes children, Meta meta) : Ctor(ctx, NodeTags, std::move(children), std::move(meta)) {} HILTI_NODE_1(ctor::Map, Ctor, final); }; } // namespace hilti::ctor