Armin Ronacher avatar Armin Ronacher committed 3458093

Attach arrays to the name not the type for C++ domain and fixed a few rendering errors.

Comments (0)

Files changed (2)

 
          Describe a casting operator here.
 
+      .. cpp:function:: constexpr void foo(std::string &bar[2]) noexcept
+
+         Describe a constexpr function here.
+
       .. cpp:member:: std::string theclass::name
 
+      .. cpp:member:: std::string theclass::name[N][M]
+
       .. cpp:type:: theclass::const_iterator
 
    Will be rendered like this:
 
          Describe a casting operator here.
 
+      .. cpp:function:: constexpr void foo(std::string &bar[2]) noexcept
+
+         Describe a constexpr function here.
+
       .. cpp:member:: std::string theclass::name
 
+      .. cpp:member:: std::string theclass::name[N][M]
+
       .. cpp:type:: theclass::const_iterator
 
 .. rst:directive:: .. cpp:namespace:: namespace

sphinx/domains/cpp.py

 _string_re = re.compile(r"[LuU8]?('([^'\\]*(?:\\.[^'\\]*)*)'"
                         r'|"([^"\\]*(?:\\.[^"\\]*)*)")', re.S)
 _visibility_re = re.compile(r'\b(public|private|protected)\b')
-_array_def_re = re.compile(r'\[\s*(.+?)?\s*\]')
+_array_def_re = re.compile(r'\[\s*([^\]]+?)?\s*\]')
 _template_arg_re = re.compile(r'(%s)|([^,>]+)' % _string_re.pattern, re.S)
 _operator_re = re.compile(r'''(?x)
         \[\s*\]
         return u'::'.join(map(unicode, self.path))
 
 
+class ArrayTypeSuffixDefExpr(object):
+
+    def __init__(self, size_hint=None):
+        self.size_hint = size_hint
+
+    def get_id_suffix(self):
+        return 'A'
+
+    def __unicode__(self):
+        return u'[%s]' % (
+            self.size_hint is not None and unicode(self.size_hint) or u'',
+        )
+
+
 class TemplateDefExpr(PrimaryDefExpr):
 
     def __init__(self, typename, args):
         return u'%s*' % self.typename
 
 
-class ArrayDefExpr(WrappingDefExpr):
-
-    def __init__(self, typename, size_hint=None):
-        WrappingDefExpr.__init__(self, typename)
-        self.size_hint = size_hint
-
-    def get_id(self):
-        return self.typename.get_id() + u'A'
-
-    def __unicode__(self):
-        return u'%s[%s]' % (
-            self.typename,
-            self.size_hint is not None and unicode(self.size_hint) or u''
-        )
-
-
 class LValRefDefExpr(WrappingDefExpr):
 
     def get_id(self):
 
 class ArgumentDefExpr(DefExpr):
 
-    def __init__(self, type, name, default=None):
+    def __init__(self, type, name, type_suffixes, default=None):
         self.name = name
         self.type = type
+        self.type_suffixes = type_suffixes
         self.default = default
 
     def get_name(self):
         return self.name.get_name()
 
     def get_id(self):
-        if self.type is None:
-            return 'X'
-        return self.type.get_id()
+        buf = []
+        buf.append(self.type and self.type.get_id() or 'X')
+        for suffix in self.type_suffixes:
+            buf.append(suffix.get_id_suffix())
+        return u''.join(buf)
 
     def __unicode__(self):
-        return (u'%s %s' % (self.type or u'', self.name or u'')).strip() + \
-               (self.default is not None and u'=%s' % self.default or u'')
+        buf = [(u'%s %s' % (self.type or u'', self.name or u'')).strip()]
+        if self.default is not None:
+            buf.append('=%s' % self.default)
+        for suffix in self.type_suffixes:
+            buf.append(unicode(suffix))
+        return u''.join(buf)
 
 
 class NamedDefExpr(DefExpr):
 
 class TypeObjDefExpr(NamedDefExpr):
 
-    def __init__(self, name, visibility, static, typename):
+    def __init__(self, name, visibility, static, typename, type_suffixes):
         NamedDefExpr.__init__(self, name, visibility, static)
         self.typename = typename
+        self.type_suffixes = type_suffixes
 
     def get_id(self):
         if self.typename is None:
-            return self.name.get_id()
-        return u'%s__%s' % (self.name.get_id(), self.typename.get_id())
+            buf = [self.name.get_id()]
+        else:
+            buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
+        for suffix in self.type_suffixes:
+            buf.append(suffix.get_id_suffix())
+        return u''.join(buf)
 
     def __unicode__(self):
         buf = self.get_modifiers()
             buf.append(unicode(self.name))
         else:
             buf.extend(map(unicode, (self.typename, self.name)))
-        return u' '.join(buf)
+        buf = [u' '.join(buf)]
+        for suffix in self.type_suffixes:
+            buf.append(unicode(suffix))
+        return u''.join(buf)
 
 
 class MemberObjDefExpr(NamedDefExpr):
 
-    def __init__(self, name, visibility, static, typename, value):
+    def __init__(self, name, visibility, static, typename, type_suffixes,
+                 value):
         NamedDefExpr.__init__(self, name, visibility, static)
         self.typename = typename
+        self.type_suffixes = type_suffixes
         self.value = value
 
     def get_id(self):
-        return u'%s__%s' % (self.name.get_id(), self.typename.get_id())
+        buf = [u'%s__%s' % (self.name.get_id(), self.typename.get_id())]
+        for suffix in self.type_suffixes:
+            buf.append(suffix.get_id_suffix())
+        return u''.join(buf)
 
     def __unicode__(self):
         buf = self.get_modifiers()
-        buf.append(u'%s %s' % (self.typename, self.name))
+        buf.extend((unicode(self.typename), unicode(self.name)))
+        buf = [u' '.join(buf)]
+        for suffix in self.type_suffixes:
+            buf.append(unicode(suffix))
         if self.value is not None:
-            buf.append(u'= %s' % self.value)
-        return u' '.join(buf)
+            buf.append(u' = %s' % self.value)
+        return u''.join(buf)
 
 
 class FuncDefExpr(NamedDefExpr):
                 expr = ConstDefExpr(expr)
             elif self.skip_string('*'):
                 expr = PtrDefExpr(expr)
-            elif self.match(_array_def_re):
-                expr = ArrayDefExpr(expr, self.last_match.group(1))
             elif self.skip_string('&'):
                 if self.skip_string('&'):
                     expr = RValRefDefExpr(expr)
             else:
                 return expr
 
+    def _try_parse_type_suffixes(self):
+        rv = []
+        while self.match(_array_def_re):
+            rv.append(ArrayTypeSuffixDefExpr(self.last_match.group(1)))
+            self.skip_ws()
+        return rv
+
     def _peek_const(self, path):
         try:
             path.remove('const')
                 self.skip_ws()
 
             if self.skip_string('...'):
-                args.append(ArgumentDefExpr(None, '...', None))
+                args.append(ArgumentDefExpr(None, '...', [], None))
                 if self.skip_string(')'):
                     break
                 else:
                     self.fail('expected closing parenthesis after ellipses')
 
+            argname = default = None
             argtype = self._parse_type()
-            argname = default = None
             self.skip_ws()
+            type_suffixes = self._try_parse_type_suffixes()
             if self.skip_string('='):
-                self.pos += 1
                 default = self._parse_default_expr()
             elif self.current_char not in ',)':
                 argname = self._parse_name()
                 self.skip_ws()
+                type_suffixes.extend(self._try_parse_type_suffixes())
                 if self.skip_string('='):
                     default = self._parse_default_expr()
+            if argname is None:
+                argname = argtype
+                argtype = None
 
-            args.append(ArgumentDefExpr(argtype, argname, default))
+            args.append(ArgumentDefExpr(argtype, argname, type_suffixes, default))
         self.skip_ws()
         const = self.skip_word_and_ws('const')
         noexcept = self.skip_word_and_ws('noexcept')
         self.skip_ws()
         if not self.eof:
             name = self._parse_type()
+            type_suffixes = self._try_parse_type_suffixes()
         else:
             name = typename
             typename = None
-        return TypeObjDefExpr(name, visibility, static, typename)
+            type_suffixes = []
+        return TypeObjDefExpr(name, visibility, static, typename, type_suffixes)
 
     def parse_member_object(self):
         visibility, static = self._parse_visibility_static()
         typename = self._parse_type()
         name = self._parse_type()
+        type_suffixes = self._try_parse_type_suffixes()
         self.skip_ws()
         if self.skip_string('='):
             value = self.read_rest().strip()
         else:
             value = None
-        return MemberObjDefExpr(name, visibility, static, typename, value)
+        return MemberObjDefExpr(name, visibility, static, typename,
+                                type_suffixes, value)
 
     def parse_function(self):
         visibility, static = self._parse_visibility_static()
             node += addnodes.desc_addname(owner, owner)
         node += addnodes.desc_name(varname, varname)
 
+    def attach_type_suffixes(self, node, suffixes):
+        for suffix in suffixes:
+            node += nodes.Text(unicode(suffix))
+
     def attach_type(self, node, type):
         # XXX: link to c?
         text = unicode(type)
         if obj.static:
             node += addnodes.desc_annotation('static', 'static')
             node += nodes.Text(' ')
+        if getattr(obj, 'constexpr', False):
+            node += addnodes.desc_annotation('constexpr', 'constexpr')
+            node += nodes.Text(' ')
 
     def add_target_and_index(self, sigobj, sig, signode):
         theid = sigobj.get_id()
             self.attach_type(signode, obj.typename)
             signode += nodes.Text(' ')
         self.attach_name(signode, obj.name)
+        self.attach_type_suffixes(signode, obj.type_suffixes)
 
 
 class CPPMemberObject(CPPObject):
         self.attach_type(signode, obj.typename)
         signode += nodes.Text(' ')
         self.attach_name(signode, obj.name)
+        self.attach_type_suffixes(signode, obj.type_suffixes)
         if obj.value is not None:
             signode += nodes.Text(u' = ' + obj.value)
 
                 self.attach_type(param, arg.type)
                 param += nodes.Text(u' ')
             param += nodes.emphasis(unicode(arg.name), unicode(arg.name))
+            self.attach_type_suffixes(param, arg.type_suffixes)
             if arg.default is not None:
                 def_ = u'=' + unicode(arg.default)
                 param += nodes.emphasis(def_, def_)
         node += paramlist
         if func.const:
             node += addnodes.desc_addname(' const', ' const')
+        if func.noexcept:
+            node += addnodes.desc_addname(' noexcept', ' noexcept')
         if func.pure_virtual:
             node += addnodes.desc_addname(' = 0', ' = 0')
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.