Steal comment of nested namespace

This commit is contained in:
Jonathan Müller 2017-12-22 10:54:37 +01:00
commit 755f251da9
10 changed files with 52 additions and 35 deletions

View file

@ -167,7 +167,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_class(const detail::parse_context&
== CXCursor_UnexposedAttr) // I have no idea what this is, but happens on Windows
// other children due to templates and stuff
return;
else if (auto entity = parse_entity(context, child))
else if (auto entity = parse_entity(context, &builder.get(), child))
builder.add_child(std::move(entity));
});
}

View file

@ -54,7 +54,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_friend(const detail::parse_context
// for some reason libclang gives a type ref here
// we actually need a class decl cursor, so parse the referenced one
// this might be a definition, so give friend information to the parser
entity = parse_entity(context, referenced, cur);
entity = parse_entity(context, nullptr, referenced, cur);
comment = type_safe::copy(entity->comment()).value_or("");
}
}
@ -74,7 +74,7 @@ std::unique_ptr<cpp_entity> detail::parse_cpp_friend(const detail::parse_context
}
else if (clang_isDeclaration(kind))
{
entity = parse_entity(context, child, cur);
entity = parse_entity(context, nullptr, child, cur);
if (entity)
{
// steal comment

View file

@ -30,7 +30,7 @@ std::unique_ptr<cpp_entity> detail::try_parse_cpp_language_linkage(const parse_c
auto builder = cpp_language_linkage::builder(name.c_str());
context.comments.match(builder.get(), cur);
detail::visit_children(cur, [&](const CXCursor& child) {
auto entity = parse_entity(context, child);
auto entity = parse_entity(context, &builder.get(), child);
if (entity)
builder.add_child(std::move(entity));
});

View file

@ -504,7 +504,7 @@ std::unique_ptr<cpp_file> libclang_parser::do_parse(const cpp_entity_index& idx,
macro_iter != preprocessed.macros.end() && macro_iter->line <= line; ++macro_iter)
builder.add_child(std::move(macro_iter->macro));
auto entity = detail::parse_entity(context, cur);
auto entity = detail::parse_entity(context, &builder.get(), cur);
if (entity)
builder.add_child(std::move(entity));
}

View file

@ -27,15 +27,19 @@ namespace
// C++17 nested namespace declarations get one cursor per nested name.
// The first cursor starts with the `namespace` keyword, and the
// following start with the `::` separator. Either way, it is skipped.
auto is_nested = false;
if (!detail::skip_if(stream, "namespace"))
skip(stream, "::");
{
is_nested = true;
skip(stream, "::");
}
auto attributes = parse_attributes(stream);
// <identifier> {
// or when anonymous: {
if (detail::skip_if(stream, "{"))
return cpp_namespace::builder("", is_inline);
return cpp_namespace::builder("", is_inline, false);
auto& name = stream.get().value();
@ -45,23 +49,32 @@ namespace
// If the next token is not `::`, there are no more nested namespace
// names, and we expect to see an opening brace.
if (!detail::skip_if(stream, "::"))
skip(stream, "{");
skip(stream, "{");
auto result = cpp_namespace::builder(name.c_str(), is_inline);
auto result = cpp_namespace::builder(name.c_str(), is_inline, is_nested);
result.get().add_attribute(attributes);
return result;
}
}
std::unique_ptr<cpp_entity> detail::parse_cpp_namespace(const detail::parse_context& context,
const CXCursor& cur)
cpp_entity& parent, const CXCursor& cur)
{
DEBUG_ASSERT(cur.kind == CXCursor_Namespace, detail::assert_handler{});
auto builder = make_ns_builder(context, cur);
context.comments.match(builder.get(), cur);
if (builder.get().is_nested())
{
// steal comment from parent
DEBUG_ASSERT(parent.kind() == cpp_namespace::kind(), detail::assert_handler{});
builder.get().set_comment(type_safe::copy(parent.comment()));
parent.set_comment(type_safe::nullopt);
}
else
context.comments.match(builder.get(), cur);
detail::visit_children(cur, [&](const CXCursor& cur) {
auto entity = parse_entity(context, cur);
auto entity = parse_entity(context, &builder.get(), cur);
if (entity)
builder.add_child(std::move(entity));
});

View file

@ -112,8 +112,8 @@ namespace
}
std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& context,
const CXCursor& cur,
const CXCursor& parent_cur) try
cpp_entity* parent, const CXCursor& cur,
const CXCursor& parent_cur) try
{
if (context.logger->is_verbose())
{
@ -138,7 +138,8 @@ std::unique_ptr<cpp_entity> detail::parse_entity(const detail::parse_context& co
break;
case CXCursor_Namespace:
return parse_cpp_namespace(context, cur);
DEBUG_ASSERT(parent, detail::assert_handler{});
return parse_cpp_namespace(context, *parent, cur);
case CXCursor_NamespaceAlias:
return parse_cpp_namespace_alias(context, cur);
case CXCursor_UsingDirective:

View file

@ -112,7 +112,7 @@ namespace cppast
const parse_context& context, const CXCursor& cur);
std::unique_ptr<cpp_entity> parse_cpp_namespace(const parse_context& context,
const CXCursor& cur);
cpp_entity& parent, const CXCursor& cur);
std::unique_ptr<cpp_entity> parse_cpp_namespace_alias(const parse_context& context,
const CXCursor& cur);
std::unique_ptr<cpp_entity> parse_cpp_using_directive(const parse_context& context,
@ -162,9 +162,10 @@ namespace cppast
std::unique_ptr<cpp_entity> parse_cpp_static_assert(const parse_context& context,
const CXCursor& cur);
// parent: used for nested namespace, doesn't matter otherwise
// parent_cur: used when parsing templates or friends
std::unique_ptr<cpp_entity> parse_entity(
const parse_context& context, const CXCursor& cur,
const parse_context& context, cpp_entity* parent, const CXCursor& cur,
const CXCursor& parent_cur = clang_getNullCursor());
}
} // namespace cppast::detail

View file

@ -35,7 +35,7 @@ namespace
DEBUG_ASSERT(!clang_Cursor_isNull(result), detail::parse_error_handler{}, cur,
"missing child of template");
auto entity = detail::parse_entity(context, result, cur);
auto entity = detail::parse_entity(context, nullptr, result, cur);
if (!entity)
return type_safe::nullopt;
DEBUG_ASSERT(p(entity->kind()), detail::parse_error_handler{}, cur,