crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.42k stars 1.62k forks source link

[Docs generator] Extended external classes/structs/modules do not get documented #11180

Open vypxl opened 3 years ago

vypxl commented 3 years ago

In my shard, I extend a struct from another library by adding some convenience methods. I defined an alias in my namespace to the struct in the external namespace.

Now, crystal docs just generates a page with the alias definition (which contains an invalid link to the external struct) without bothering to create a page with the new methods.

This, however, only happens when I extend a class/struct/module that a library already defined (see notes)

Steps to reproduce:

src/main.cr

require "a"

module B alias Test = A::Test struct A::Test

Multiplies @prop with the given factor

def multiply(factor)
  @prop * factor
end

end end

test = B::Test.new(3) puts test.multiply(5)


- Generate docs: `crystal docs --project-name Test --project-version 1.0.0`
- Result:
![screenshot](https://user-images.githubusercontent.com/13833431/132334842-862a100f-2976-4c2b-8432-3781a270df89.png)

### Expectation
My expectation was that this would generate another page under the `A` module in which the added methods were described.

### Notes

- When the alias is removed, no page is generated at all
- When the external struct from module A is extended at the toplevel (not inside module B), the result is the same
- When no library defines module A, the result is as expected
straight-shoota commented 3 years ago

Your code shouldn't even compile.

For some reason, module B; struct A::Test; reopens ::A::Test. That's wrong. It should actually create a new type B::A::Test because the struct definition is in the B namespace.

I suppose the docs generator might be expecting this and that's the reason why it doesn't even show A::Test. It would be documented if you remove the B namespace.

vypxl commented 3 years ago

@straight-shoota You are right, that is, however, another issue I was not even going for ^^ (but the code above compiles, btw i don't know why though).

I did a little research on my end:

It seems that my issue has a different root cause. For some reason, if I extend the external struct like this:

module A
  struct Test
    def method(); end
  end
end

it is documented as expected.

If I write the short form like this:

struct A::Test
  def method(); end
end

it is not documented.

If I declare a new struct B::Test, everything works just fine.

Somehow, the short form is treated differently than the verbose one.

vypxl commented 3 years ago

Another observation:

When I include a module A; end somewhere in the project, everything works as intended, even when using the short form.

vypxl commented 3 years ago

This issue does not seem to fit the discription above anymore, should I edit it or open a new one?