From 75c67ab5cd6bc0faeede6198943a7bdc02a7deed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sat, 21 Jan 2017 13:15:13 +0100 Subject: [PATCH] Add cpp_namespace_alias --- include/cppast/cpp_entity_type.hpp | 15 ++++++++ include/cppast/cpp_namespace.hpp | 56 ++++++++++++++++++++++++++++++ src/cpp_entity_type.cpp | 1 + src/cpp_namespace.cpp | 11 ++++++ 4 files changed, 83 insertions(+) diff --git a/include/cppast/cpp_entity_type.hpp b/include/cppast/cpp_entity_type.hpp index 838624c..34f673f 100644 --- a/include/cppast/cpp_entity_type.hpp +++ b/include/cppast/cpp_entity_type.hpp @@ -5,6 +5,8 @@ #ifndef CPPAST_CPP_ENTITY_TYPE_HPP_INCLUDED #define CPPAST_CPP_ENTITY_TYPE_HPP_INCLUDED +#include + namespace cppast { /// All possible types of C++ entities. @@ -13,10 +15,23 @@ namespace cppast file_t, namespace_t, + namespace_alias_t, }; /// \returns Whether or not a given entity type is one derived from [cppast::cpp_scope](). bool is_scope(cpp_entity_type type) noexcept; + + /// \exclude + namespace detail + { + template + T downcast_entity(Org& org, cpp_entity_type dest_type) noexcept + { + DEBUG_ASSERT(org.type() == dest_type, detail::precondition_error_handler{}, + "invalid downcast"); + return static_cast(org); + } + } // namespace detail } // namespace cppast #endif // CPPAST_CPP_ENTITY_TYPE_HPP_INCLUDED diff --git a/include/cppast/cpp_namespace.hpp b/include/cppast/cpp_namespace.hpp index b6e4ba5..af0286b 100644 --- a/include/cppast/cpp_namespace.hpp +++ b/include/cppast/cpp_namespace.hpp @@ -60,6 +60,62 @@ namespace cppast bool inline_; }; + + /// A reference to a [cppast::cpp_namespace](). + class cpp_namespace_ref + { + public: + /// \effects Creates it giving it the target id and name. + /// \requires A [cppast::cpp_namespace]() must register in the [cppast::cpp_entity_index]() with that id. + cpp_namespace_ref(cpp_entity_id target_id, std::string target_name) + : target_(std::move(target_id)), name_(std::move(target_name)) + { + } + + /// \returns The name of the reference, as spelled in the source code. + const std::string& name() const noexcept + { + return name_; + } + + /// \returns The [cppast::cpp_namespace]() it refers to. + const cpp_namespace& get(const cpp_entity_index& idx) const noexcept; + + private: + cpp_entity_id target_; + std::string name_; + }; + + /// A [cppast::cpp_entity]() modelling a namespace alias. + class cpp_namespace_alias final : public cpp_entity + { + public: + static std::unique_ptr build(const cpp_entity_index& idx, + cpp_entity_id id, std::string name, + cpp_namespace_ref target) + { + auto ptr = std::unique_ptr( + new cpp_namespace_alias(std::move(name), std::move(target))); + idx.register_entity(std::move(id), type_safe::ref(*ptr)); + return ptr; + } + + /// \returns The [cppast::cpp_namespace_ref]() to the aliased namespace. + const cpp_namespace_ref& target() const noexcept + { + return target_; + } + + private: + cpp_namespace_alias(std::string name, cpp_namespace_ref target) + : cpp_entity(std::move(name)), target_(std::move(target)) + { + } + + cpp_entity_type do_get_entity_type() const noexcept override; + + cpp_namespace_ref target_; + }; } // namespace cppast #endif // CPPAST_CPP_NAMESPACE_HPP_INCLUDED diff --git a/src/cpp_entity_type.cpp b/src/cpp_entity_type.cpp index b602ad3..b0bef71 100644 --- a/src/cpp_entity_type.cpp +++ b/src/cpp_entity_type.cpp @@ -14,6 +14,7 @@ bool cppast::is_scope(cpp_entity_type type) noexcept return true; case cpp_entity_type::file_t: + case cpp_entity_type::namespace_alias_t: break; } diff --git a/src/cpp_namespace.cpp b/src/cpp_namespace.cpp index bb8e706..0667433 100644 --- a/src/cpp_namespace.cpp +++ b/src/cpp_namespace.cpp @@ -12,3 +12,14 @@ cpp_entity_type cpp_namespace::do_get_entity_type() const noexcept { return cpp_entity_type::namespace_t; } + +const cpp_namespace& cpp_namespace_ref::get(const cpp_entity_index& idx) const noexcept +{ + return detail::downcast_entity(idx.lookup(target_).value(), + cpp_entity_type::namespace_t); +} + +cpp_entity_type cpp_namespace_alias::do_get_entity_type() const noexcept +{ + return cpp_entity_type::namespace_alias_t; +}