Skip to content

Commit

Permalink
Merge pull request #503 from jakobandersen/simplifications
Browse files Browse the repository at this point in the history
Simplifications and fixes
  • Loading branch information
vermeeren authored Apr 17, 2020
2 parents 18d7995 + b999b31 commit 9a7cc86
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 52 deletions.
85 changes: 33 additions & 52 deletions breathe/renderer/sphinxrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,53 +30,25 @@ def __exit__(self, et, ev, bt):
self.previous = None


class DoxyCPPClassObject(cpp.CPPClassObject):
__bases = []
class DoxyCPPInterfaceObject(cpp.CPPClassObject):
object_type = 'class'

@property
def display_object_type(self):
# override because we also have the 'interface' type
assert self.objtype in ('class', 'struct', 'interface')
# TODO: remove this if it should be rendered as 'interface' as well
if self.objtype == 'interface':
return 'class'
return self.objtype
# override because we have the 'interface' type
assert self.objtype == 'interface'
return 'class' # TODO: change to 'interface' if that is the desired rendering

def parse_definition(self, parser):
# add the base classes
ast = parser.parse_declaration("class", "class")

bases = []

for base in self.__bases:
namestr = base.content_[0].value

# build a name object
# TODO: work out if we can use base.refid in a pending_xref somewhere
parser = cpp.DefinitionParser(namestr,
location=self.get_source_info(),
config=self.env.config)
name = parser._parse_nested_name()
parser.assert_end()

bases.append(
cpp.ASTBaseClass(name, base.prot, base.virt == 'virtual', False)
)

ast.declaration.bases = bases

return ast

def augment(self, bases):
self.__bases = bases or []
return parser.parse_declaration("class", "class")


class DomainDirectiveFactory(object):
# A mapping from node kinds to cpp domain classes and directive names.
cpp_classes = {
'class': (DoxyCPPClassObject, 'class'),
'struct': (DoxyCPPClassObject, 'class'),
'interface': (DoxyCPPClassObject, 'interface'),
'class': (cpp.CPPClassObject, 'class'),
'struct': (cpp.CPPClassObject, 'struct'),
'interface': (DoxyCPPInterfaceObject, 'interface'),
'function': (cpp.CPPFunctionObject, 'function'),
'friend': (cpp.CPPFunctionObject, 'function'),
'signal': (cpp.CPPFunctionObject, 'function'),
Expand Down Expand Up @@ -148,11 +120,13 @@ def create(domain, args):
cls, name = DomainDirectiveFactory.php_classes.get(
arg_0, (php.PhpClasslike, 'class'))
else:
domain = 'cpp'
cls, name = DomainDirectiveFactory.cpp_classes.get(
args[0], (cpp.CPPMemberObject, 'member'))
# Replace the directive name because domain directives don't know how to handle
# Breathe's "doxygen" directives.
args = [name] + args[1:]
assert ':' not in name
args = [domain + ':' + name] + args[1:]
return cls(*args)


Expand Down Expand Up @@ -356,13 +330,10 @@ def create_template_prefix(self, decl):
nodes = self.render(decl.templateparamlist)
return 'template<' + ''.join(n.astext() for n in nodes) + '>'

def run_domain_directive(self, kind, names, augment=None):
def run_domain_directive(self, kind, names):
domain_directive = DomainDirectiveFactory.create(
self.context.domain, [kind, names] + self.context.directive_args[2:])

if hasattr(domain_directive, 'augment') and augment is not None:
domain_directive.augment(**augment)

# Translate Breathe's no-link option into the standard noindex option.
if 'no-link' in self.context.directive_args[2]:
domain_directive.options['noindex'] = True
Expand Down Expand Up @@ -498,21 +469,33 @@ def render_signature(file_data, doxygen_target, name, kind):
templatePrefix = self.create_template_prefix(file_data.compounddef)
arg = "%s %s" % (templatePrefix, self.get_fully_qualified_name())

# add base classes
if kind in ('class', 'struct'):
augment = dict(bases=file_data.compounddef.basecompoundref)
else:
augment = None
bs = []
for base in file_data.compounddef.basecompoundref:
b = []
if base.prot is not None:
b.append(base.prot)
if base.virt == 'virtual':
b.append("virtual")
b.append(base.content_[0].value)
bs.append(" ".join(b))
if len(bs) != 0:
arg += " : "
arg += ", ".join(bs)

self.context.directive_args[1] = [arg]
nodes = self.run_domain_directive(kind, self.context.directive_args[1], augment=augment)

nodes = self.run_domain_directive(kind, self.context.directive_args[1])
rst_node = nodes[1]

finder = NodeFinder(rst_node.document)
rst_node.walk(finder)

# The cpp domain in Sphinx doesn't support structs at the moment, so change the text
# from "class " to the correct kind which can be "class " or "struct ".
finder.declarator[0] = self.node_factory.desc_annotation(kind + ' ', kind + ' ')
if kind in ('interface', 'namespace'):
# This is not a real C++ declaration type that Sphinx supports,
# so we hax the replacement of it.
finder.declarator[0] = self.node_factory.desc_annotation(kind + ' ', kind + ' ')

rst_node.children[0].insert(0, doxygen_target)
return nodes, finder.content
Expand Down Expand Up @@ -1062,10 +1045,8 @@ def update_define_signature(signature, obj_type):
return self.render_declaration(node, declaration, update_signature=update_define_signature)

def visit_enum(self, node):
# Sphinx requires a name to be a valid identifier, so replace anonymous enum name of the
# form @id generated by Doxygen with "@anon_id".
name = self.get_fully_qualified_name()
declaration = name.replace("@", "@anon_") if node.name.startswith("@") else name
declaration = name

description_nodes = self.description(node)
name = self.node_factory.emphasis("", self.node_factory.Text("Values:"))
Expand Down
1 change: 1 addition & 0 deletions documentation/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
"c_union":"../../examples/specific/c_union/xml/",
"define":"../../examples/specific/define/xml/",
"multifile":"../../examples/specific/multifilexml/xml/",
"cpp_anon":"../../examples/specific/cpp_anon/xml/",
}

breathe_projects_source = {
Expand Down
8 changes: 8 additions & 0 deletions documentation/source/specific.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,11 @@ Interface Class

.. doxygeninterface:: InterfaceClass
:project: interface

C++ Anonymous Entities
----------------------

.. cpp:namespace:: @ex_specific_cpp_anon

.. doxygenfile:: cpp_anon.h
:project: cpp_anon
1 change: 1 addition & 0 deletions examples/specific/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ projects = nutshell alias rst inline namespacefile array inheritance \
headings links parameters template_class template_class_non_type \
template_function template_type_alias template_specialisation \
enum define interface \
cpp_anon \
c_file c_struct c_enum c_typedef c_macro c_union

special = programlisting decl_impl multifilexml auto class typedef
Expand Down
11 changes: 11 additions & 0 deletions examples/specific/cpp_anon.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
PROJECT_NAME = "C++ Anonymous"
OUTPUT_DIRECTORY = cpp_anon
GENERATE_LATEX = NO
GENERATE_MAN = NO
GENERATE_RTF = NO
CASE_SENSE_NAMES = NO
INPUT = cpp_anon.h
QUIET = YES
JAVADOC_AUTOBRIEF = YES
GENERATE_HTML = NO
GENERATE_XML = YES
13 changes: 13 additions & 0 deletions examples/specific/cpp_anon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct ClassWithAnonEntities {
struct {
int structMember;
};

union {
int unionMember;
};

enum {
Enumerator
};
};

0 comments on commit 9a7cc86

Please sign in to comment.