Skip to content

Commit

Permalink
Move DomainDirectiveFactory to where it is used
Browse files Browse the repository at this point in the history
Instead of passing it down from the top. Reduces the need for the
intermediate factories which we'll hopefully eliminate at some point.

For #236.
  • Loading branch information
Michael Jones committed Jan 15, 2016
1 parent 66d5755 commit c78a410
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 63 deletions.
51 changes: 1 addition & 50 deletions breathe/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
from .node_factory import create_node_factory

from docutils.parsers.rst.directives import unchanged_required, unchanged, flag
from sphinx.domains import cpp, c, python
from sphinx.writers.text import TextWriter
from sphinx.builders.text import TextBuilder
from sphinx.domains import cpp

import os
import fnmatch
Expand Down Expand Up @@ -770,54 +770,6 @@ def purge_doc(self, app, env, docname):
del self.app.env.breathe_file_state[filename]


class DomainDirectiveFactory(object):
# A mapping from node kinds to cpp domain classes and directive names.
cpp_classes = {
'class': (cpp.CPPClassObject, 'class'),
'struct': (cpp.CPPClassObject, 'class'),
'function': (cpp.CPPFunctionObject, 'function'),
'friend': (cpp.CPPFunctionObject, 'function'),
'slot': (cpp.CPPFunctionObject, 'function'),
'enum': (cpp.CPPTypeObject, 'type'),
'typedef': (cpp.CPPTypeObject, 'type'),
'union': (cpp.CPPTypeObject, 'type'),
'namespace': (cpp.CPPTypeObject, 'type'),
# Use CPPClassObject for enum values as the cpp domain doesn't have a directive for
# enum values and CPPMemberObject requires a type.
'enumvalue': (cpp.CPPClassObject, 'member'),
'define': (c.CObject, 'macro')
}

python_classes = {
'function': (python.PyModulelevel, 'function'),
'variable': (python.PyClassmember, 'attribute')
}

@staticmethod
def fix_python_signature(sig):
def_ = 'def '
if sig.startswith(def_):
sig = sig[len(def_):]
# Doxygen uses an invalid separator ('::') in Python signatures. Replace them with '.'.
return sig.replace('::', '.')

@staticmethod
def create(domain, args):
if domain == 'c':
return c.CObject(*args)
if domain == 'py':
cls, name = DomainDirectiveFactory.python_classes.get(
args[0], (python.PyClasslike, 'class'))
args[1] = [DomainDirectiveFactory.fix_python_signature(n) for n in args[1]]
else:
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:]
return cls(*args)


# Setup
# -----

Expand All @@ -834,7 +786,6 @@ def setup(app):

renderer_factory_creator_constructor = DoxygenToRstRendererFactoryCreatorConstructor(
parser_factory,
DomainDirectiveFactory,
)

# Assume general build directory is the doctree directory without the last component. We strip
Expand Down
10 changes: 0 additions & 10 deletions breathe/renderer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def __init__(
document,
filter_,
target_handler,
domain_directive_factory
):

self.node_type = node_type
Expand All @@ -79,7 +78,6 @@ def __init__(
self.document = document
self.filter_ = filter_
self.target_handler = target_handler
self.domain_directive_factory = domain_directive_factory

def create_renderer(
self,
Expand Down Expand Up @@ -121,7 +119,6 @@ def create_renderer(
self.state,
self.document,
self.target_handler,
self.domain_directive_factory
]

if node_type == "docmarkup":
Expand Down Expand Up @@ -227,12 +224,10 @@ class DoxygenToRstRendererFactoryCreator(object):
def __init__(
self,
parser_factory,
domain_directive_factory,
project_info
):

self.parser_factory = parser_factory
self.domain_directive_factory = domain_directive_factory
self.project_info = project_info

def create_factory(self, node_stack, state, document, filter_, target_handler):
Expand Down Expand Up @@ -285,7 +280,6 @@ def create_factory(self, node_stack, state, document, filter_, target_handler):
document,
filter_,
target_handler,
self.domain_directive_factory
)

def create_child_factory(self, project_info, data_object, parent_renderer_factory):
Expand All @@ -310,7 +304,6 @@ def create_child_factory(self, project_info, data_object, parent_renderer_factor
parent_renderer_factory.document,
parent_renderer_factory.filter_,
parent_renderer_factory.target_handler,
parent_renderer_factory.domain_directive_factory
)


Expand All @@ -320,17 +313,14 @@ class DoxygenToRstRendererFactoryCreatorConstructor(object):
def __init__(
self,
parser_factory,
domain_directive_factory,
):

self.parser_factory = parser_factory
self.domain_directive_factory = domain_directive_factory

def create_factory_creator(self, project_info, document, target_handler):

return DoxygenToRstRendererFactoryCreator(
self.parser_factory,
self.domain_directive_factory,
project_info,
)

Expand Down
55 changes: 52 additions & 3 deletions breathe/renderer/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,55 @@

from sphinx.domains import cpp, c, python


class DomainDirectiveFactory(object):
# A mapping from node kinds to cpp domain classes and directive names.
cpp_classes = {
'class': (cpp.CPPClassObject, 'class'),
'struct': (cpp.CPPClassObject, 'class'),
'function': (cpp.CPPFunctionObject, 'function'),
'friend': (cpp.CPPFunctionObject, 'function'),
'slot': (cpp.CPPFunctionObject, 'function'),
'enum': (cpp.CPPTypeObject, 'type'),
'typedef': (cpp.CPPTypeObject, 'type'),
'union': (cpp.CPPTypeObject, 'type'),
'namespace': (cpp.CPPTypeObject, 'type'),
# Use CPPClassObject for enum values as the cpp domain doesn't have a directive for
# enum values and CPPMemberObject requires a type.
'enumvalue': (cpp.CPPClassObject, 'member'),
'define': (c.CObject, 'macro')
}

python_classes = {
'function': (python.PyModulelevel, 'function'),
'variable': (python.PyClassmember, 'attribute')
}

@staticmethod
def fix_python_signature(sig):
def_ = 'def '
if sig.startswith(def_):
sig = sig[len(def_):]
# Doxygen uses an invalid separator ('::') in Python signatures. Replace them with '.'.
return sig.replace('::', '.')

@staticmethod
def create(domain, args):
if domain == 'c':
return c.CObject(*args)
if domain == 'py':
cls, name = DomainDirectiveFactory.python_classes.get(
args[0], (python.PyClasslike, 'class'))
args[1] = [DomainDirectiveFactory.fix_python_signature(n) for n in args[1]]
else:
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:]
return cls(*args)


class Renderer(object):

def __init__(
Expand All @@ -10,7 +61,6 @@ def __init__(
state,
document,
target_handler,
domain_directive_factory,
):

self.project_info = project_info
Expand All @@ -21,7 +71,6 @@ def __init__(
self.state = state
self.document = document
self.target_handler = target_handler
self.domain_directive_factory = domain_directive_factory

if self.context.domain == '':
self.context.domain = self.get_domain()
Expand Down Expand Up @@ -100,7 +149,7 @@ def create_template_node(self, decl):
return signode

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

# Translate Breathe's no-link option into the standard noindex option.
Expand Down

0 comments on commit c78a410

Please sign in to comment.