Add cpp_scope_name to support templated scopes

This commit is contained in:
Jonathan Müller 2017-04-13 11:58:52 +02:00
commit 06cf090b35
7 changed files with 75 additions and 15 deletions

View file

@ -223,10 +223,9 @@ namespace cppast
cpp_entity_kind do_get_entity_kind() const noexcept override;
/// \returns The name of the namespace.
type_safe::optional<std::string> do_get_scope_name() const override
type_safe::optional<cpp_scope_name> do_get_scope_name() const override
{
return name();
return type_safe::ref(*this);
}
detail::intrusive_list<cpp_base_class> bases_;

View file

@ -11,9 +11,40 @@
namespace cppast
{
class cpp_entity;
enum class cpp_entity_kind;
class cpp_entity_index;
struct cpp_entity_id;
class cpp_template_parameter;
class cpp_template;
/// The name of a scope.
///
/// It is a combination of a name and optional template parameters.
class cpp_scope_name
{
public:
/// \effects Creates a scope out of a given entity.
cpp_scope_name(type_safe::object_ref<const cpp_entity> entity);
/// \returns The name of the scope.
const std::string& name() const noexcept;
/// \returns Whether or not the scope is templated.
bool is_templated() const noexcept
{
return templ_.has_value();
}
/// \returns An iteratable object iterating over the [cppast::cpp_template_parameter]() entities of the scope.
/// \requires The scope is templated.
detail::iteratable_intrusive_list<cpp_template_parameter> template_parameters() const
noexcept;
private:
type_safe::object_ref<const cpp_entity> entity_;
type_safe::optional_ref<const cpp_template> templ_;
};
/// The base class for all entities in the C++ AST.
class cpp_entity : detail::intrusive_list_node<cpp_entity>
@ -39,7 +70,7 @@ namespace cppast
/// \returns The name of the new scope created by the entity,
/// if there is any.
type_safe::optional<std::string> scope_name() const
type_safe::optional<cpp_scope_name> scope_name() const
{
return do_get_scope_name();
}
@ -100,7 +131,7 @@ namespace cppast
/// \returns The name of the new scope created by the entity, if any.
/// By default, there is no scope created.
virtual type_safe::optional<std::string> do_get_scope_name() const
virtual type_safe::optional<cpp_scope_name> do_get_scope_name() const
{
return type_safe::nullopt;
}

View file

@ -134,9 +134,7 @@ namespace cppast
cpp_entity_kind do_get_entity_kind() const noexcept override;
/// \returns If the enum is scoped, the name of the enum,
/// otherwise [ts::nullopt]().
type_safe::optional<std::string> do_get_scope_name() const override;
type_safe::optional<cpp_scope_name> do_get_scope_name() const override;
std::unique_ptr<cpp_type> type_;
bool scoped_, type_given_;

View file

@ -74,10 +74,9 @@ namespace cppast
cpp_entity_kind do_get_entity_kind() const noexcept override;
/// \returns The name of the namespace.
type_safe::optional<std::string> do_get_scope_name() const override
type_safe::optional<cpp_scope_name> do_get_scope_name() const override
{
return name();
return type_safe::ref(*this);
}
bool inline_;

View file

@ -6,9 +6,38 @@
#include <cppast/cpp_entity_index.hpp>
#include <cppast/cpp_entity_kind.hpp>
#include <cppast/cpp_template.hpp>
using namespace cppast;
cpp_scope_name::cpp_scope_name(type_safe::object_ref<const cpp_entity> entity) : entity_(entity)
{
if (cppast::is_templated(*entity))
{
auto& templ = static_cast<const cpp_template&>(entity->parent().value());
if (!templ.parameters().empty())
templ_ = type_safe::ref(templ);
}
else if (is_template(entity->kind()))
{
auto& templ = static_cast<const cpp_template&>(*entity);
if (!templ.parameters().empty())
templ_ = type_safe::ref(templ);
}
}
const std::string& cpp_scope_name::name() const noexcept
{
return entity_->name();
}
detail::iteratable_intrusive_list<cpp_template_parameter> cpp_scope_name::template_parameters()
const noexcept
{
DEBUG_ASSERT(is_templated(), detail::precondition_error_handler{});
return templ_.value().parameters();
}
cpp_entity_kind cpp_unexposed_entity::kind() noexcept
{
return cpp_entity_kind::unexposed_t;

View file

@ -38,7 +38,9 @@ cpp_entity_kind cpp_enum::do_get_entity_kind() const noexcept
return kind();
}
type_safe::optional<std::string> cpp_enum::do_get_scope_name() const
type_safe::optional<cpp_scope_name> cpp_enum::do_get_scope_name() const
{
return scoped_ ? type_safe::make_optional(name()) : type_safe::nullopt;
if (scoped_)
return type_safe::ref(*this);
return type_safe::nullopt;
}

View file

@ -140,6 +140,7 @@ unsigned count_children(const Entity& cont)
return std::distance(cont.begin(), cont.end());
}
// ignores templated scopes
inline std::string full_name(const cppast::cpp_entity& e)
{
if (e.name().empty())
@ -152,8 +153,9 @@ inline std::string full_name(const cppast::cpp_entity& e)
for (auto cur = e.parent(); cur; cur = cur.value().parent())
// prepend each scope, if there is any
type_safe::with(cur.value().scope_name(),
[&](const std::string& cur_scope) { scopes = cur_scope + "::" + scopes; });
type_safe::with(cur.value().scope_name(), [&](const cppast::cpp_scope_name& cur_scope) {
scopes = cur_scope.name() + "::" + scopes;
});
return scopes + e.name();
}