jessevdk / cldoc

clang based documentation generator for C and C++
GNU General Public License v2.0
553 stars 59 forks source link

AttributeError: 'Namespace' object has no attribute 'bases' #73

Open OmnipotentEntity opened 9 years ago

OmnipotentEntity commented 9 years ago

Hi there,

I'm setting up cldocs on a largish (120k sloc) codebase. Partway through I got this traceback:

Processing StarCircle.hpp
Traceback (most recent call last):
  File "/usr/local/bin/cldoc", line 9, in <module>
    load_entry_point('cldoc==1.6', 'console_scripts', 'cldoc')()
  File "/usr/local/lib/python2.7/site-packages/cldoc/__init__.py", line 57, in run
    run_generate(rest)
  File "/usr/local/lib/python2.7/site-packages/cldoc/__init__.py", line 27, in run_generate
    cmdgenerate.run(args)
  File "/usr/local/lib/python2.7/site-packages/cldoc/cmdgenerate.py", line 151, in run
    run_generate(t, opts)
  File "/usr/local/lib/python2.7/site-packages/cldoc/cmdgenerate.py", line 33, in run_generate
    generator.generate(xmlout)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 55, in generate
    Generator.generate(self, outdir)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/generator.py", line 22, in generate
    self.generate_node(node)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 543, in generate_node
    self.generate_page(node)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 510, in generate_page
    elem = self.node_to_xml(node)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 496, in node_to_xml
    chelem = self.node_to_xml(child)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 485, in node_to_xml
    self.call_type_specific(node, elem, 'to_xml')
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 465, in call_type_specific
    getattr(self, nm)(node, elem)
  File "/usr/local/lib/python2.7/site-packages/cldoc/generators/xml.py", line 273, in method_to_xml
    if len(node.override) > 0:
  File "/usr/local/lib/python2.7/site-packages/cldoc/nodes/method.py", line 43, in override
    bases = list(self.parent.bases)
AttributeError: 'Namespace' object has no attribute 'bases'

The command line issued is too long to be pasted here but can be found at http://pastebin.com/JxWf9hRB

The contents of StarCircle.hpp can be found at http://pastebin.com/yxnpNEK7

When documenting just StarCircle it completes without issue. So does StarClock.hpp (the next file). Unfortunately, I don't have any ideas on what steps to take beyond this.

Is this a bug, or am I doing something wrong?

jessevdk commented 9 years ago

This is most certainly a bug. It's a little bit hard to debug since I'm not sure how to reproduce the issue. The problem seems to be that the parent of a Method node isn't set correctly (only classes should be parents of methods, not namespaces). It would be great if you could produce a small failing test case.

OmnipotentEntity commented 9 years ago

I'll do my best.

OmnipotentEntity commented 9 years ago

Ok, here is a minimal example of this issue:

template<typename T>
struct Foo {
  int baz(T const& t) const { }
};

template<typename T, int N>
class Bar { };

template<typename T, int N>
struct Foo<Bar<T, N>> {
  int baz(Bar<T, N> const& a) const;
};

template<typename T, int N>
int Foo<Bar<T, N>>::baz(Bar<T, N> const& a) const { }

Whereas this works:

template<typename T>
struct Foo {
  int baz(T const& t) const { }
};

template<typename T, int N>
class Bar { };

template<typename T, int N>
struct Foo<Bar<T, N>> {
  int baz(Bar<T, N> const& a) const { }
};

Command:

cldoc generate -std=c++11 -- --output html ./min.cpp
jessevdk commented 9 years ago

Ok, I found the issue which is that cldoc doesn't yet have support for partial template specializations. I'll have to take a deeper look into how to properly implement this.

OmnipotentEntity commented 9 years ago

Ugh, I knew I should have tested every single damn part before reporting. I had originally pared this down from the StarArray.hpp file, which meant I eventually wound up with the file named StarArray-it10.hpp. I figured that filename wouldn't matter, so I didn't test it.

Files ending in .cc or .cpp work with the given test code. Files ending in .h or .hpp don't.

jessevdk commented 9 years ago

I think that's something else. cldoc only generates documentation for public API. If there is no header (i.e. declaration) of a symbol associated to the definition of it, then it will skip that symbol.

OmnipotentEntity commented 9 years ago

That's actually good information for me. That means essentially that I don't need to run this on .cpp files at all?

amorozov commented 9 years ago

The following patch fixes symptoms of the problem, probably not the reason. The reason as it seems to me, is that the method definition is processed in the global context, with self.parent being equal to Root or Namespace, not the Class. I'm not sure that this doesn't lead to mistakes in doc generation, but at least it doesn't explode.

diff --git a/cldoc/nodes/method.py b/cldoc/nodes/method.py
index f910241..3e1208f 100644
--- a/cldoc/nodes/method.py
+++ b/cldoc/nodes/method.py
@@ -40,7 +40,7 @@ class Method(Function):
              return self._override

         # Lookup in bases, recursively
-        bases = list(self.parent.bases)
+        bases = list(getattr(self.parent, "bases", []))
         mname = self.name

         self._override = []
jessevdk commented 9 years ago

This is indeed not the cause of the problem, and fixing it like that would just hide the underlying issues. The actual issue is that cldoc does not handle the partial specialization node kind (it actually outputs this also at the top normally). Since the template specialization class is not being registered, it will not be found when resolving the parent of the method which then results in the scope just above (in this case the namespace).

jeaye commented 9 years ago

Just chiming in to say that I'm also getting this, manifesting as

AttributeError: 'Root' object has no attribute 'bases'

For now, I've patched locally as per @amorozov's suggestion (thanks). Thanks for keeping us updated.

topisani commented 7 years ago

What's the state of this? Reffering to both this issue and the project in general...