Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java: linebreak after @link can cause wrong parsing of subsequent doc #8511

Open
Stewori opened this issue Apr 20, 2021 · 11 comments
Open

Java: linebreak after @link can cause wrong parsing of subsequent doc #8511

Stewori opened this issue Apr 20, 2021 · 11 comments

Comments

@Stewori
Copy link

Stewori commented Apr 20, 2021

Describe the bug
Processing Java code

public class A {

    /**
     * A linebreak in a link {@link
     * A}
     *
     * @param  <S> can cause trouble
     */
    public static void test(Class<S> cls) {}
}

makes doxygen invent an <s> tag in xml output:

<detaileddescription>
<para>A linebreak in a link {<ref refid="classA" kindref="compound">}  <s> can cause trouble </s></ref></para>
</detaileddescription>

This is triggered by the linebreak in @link. If one writes it as a one-liner * A linebreak in a link {@link A}
one gets the expected behavior described below.

Expected behavior
I expect the xml output to be the same as if the @link was written as a one-liner:

<detaileddescription>
<para>A linebreak in a link <ref refid="classA" kindref="compound">A</ref></para>
<para><parameterlist kind="param"><parameteritem>
<parameternamelist>
<parametername>&lt;S&gt;</parametername>
</parameternamelist>
<parameterdescription>
<para>can cause trouble </para>
</parameterdescription>
</parameteritem>
</parameterlist>
</para>
</detaileddescription>

To Reproduce
Find a Java file and doxygen config attached. The issue is demonstrated like mentioned above.
After running doxygen on the example, the files in the subfolder xml contain the snippets shown above.
issue_param_s.zip

Version
Tested with doxygen clone from 2021-04-11:

/blah/doxygen/build/bin/doxygen -v
1.9.2 (e9185650216f3c3fa97759caf67ee79db66cb5e1)

lsb_release -a:

LSB Version:	core-9.20160110ubuntu0.2-amd64:core-9.20160110ubuntu0.2-noarch:security-9.20160110ubuntu0.2-amd64:security-9.20160110ubuntu0.2-noarch
Distributor ID:	LinuxMint
Description:	Linux Mint 18 Sarah
Release:	18
Codename:	sarah

Additional context
This is not an academic issue, it actually occurs in Java standard library. More specifically it occurs in java.util.ServiceLoader.load which is part of the java.base module, which in turn is a dependency for every Java program. One use case to process the Java standard library with doxygen is to work around issue #8433. This also explains why it is not a simple solution to just manually rewrite the javadoc to avoid linebreaks after @link.
Edit: I admit it is not crucial to have all javadoc processed totally cleanly, just in order to work around #8433. Anyway, I happened to notice this issue during such a task.

albert-github added a commit to albert-github/doxygen that referenced this issue Apr 20, 2021
…g of subsequent doc

Allowing also a `\n` after the @link.
@albert-github
Copy link
Collaborator

The created syntax (with the \n in the link) is not a situation I would advise to use, but I've just pushed a proposed patch, pull request #8512

Note the given example has a small flaw:

 @param  <S> can cause trouble

should read:
@param cls can cause trouble

as the parameter is `cls`.

@Stewori
Copy link
Author

Stewori commented Apr 20, 2021

Note the given example has a small flaw

It appears to be common (e.g. in the Java standard library) to use @param to describe generic parameters such as S. I simplified the issue from a situation like public static <S> Something<S> test(Class<S> cls), where it is probably more understandable why one would have a parameter description in the method doc. In a more verbose doc comment one might have:

    /**
     * Story what method test is good for.
     *
     * @param  <S> explanation what the generic parameter S is about.
     * @param  cls explanation what the parameter cls is about.
     */
    public static <S> Something<S> test(Class<S> cls)
    {
        ...
        return new Something<S>(...);
    }

I simplified it as far as possible to pin the issue as precisely as possible. I guess the occurrence of @param <S> ... is crucial to trigger the unfortunate "invention" of an <s> tag.

The created syntax (with the \n in the link) is not a situation I would advise to use

Neither would I. Unfortunately I observed it "in the wild". Probably due to long class names and maximum line width conventions.

Thanks for fixing this so quickly! Will check it out...

@albert-github
Copy link
Collaborator

It appears to be common (e.g. in the Java standard library) to use @param to describe generic parameters such as S.

Is there any reference to this (in the definitions of the @param for java?

Note: that it was an <S> was just a nice bonus is showing the issue in the output.

@Stewori
Copy link
Author

Stewori commented Apr 21, 2021

I see, the linebreak nukes the param-list no matter whether it starts with <S> or something else. Then it was luck I found the issue because my code alerted me of an unknown tag <s>.

Is there any reference to this (in the definitions of the @param for java?

Just looked it up and it confirms the explained use for type parameters:

The parameter-name can be the name of a parameter in a method or constructor, or the name of a type parameter of a class, method or constructor. Use angle brackets around this parameter name to specify the use of a type parameter.

@albert-github
Copy link
Collaborator

Looks a bit like doxygen uses for this the \tparam command, though here again the Class is not present.

This template issue is of course different from the original linebreak issue, so best is to create an new issue for this template issue.

doxygen added a commit that referenced this issue Apr 29, 2021
issue #8511 Java: linebreak after @link can cause wrong parsing of subsequent doc
@albert-github
Copy link
Collaborator

Code has been integrated in master on github (please don't close the issue as this will be done at the moment of an official release).

@albert-github albert-github added the fixed but not released Bug is fixed in github, but still needs to make its way to an official release label Apr 29, 2021
@Stewori
Copy link
Author

Stewori commented Apr 29, 2021

This template issue is of course different from the original linebreak issue, so best is to create an new issue for this template issue.

So far, I am not really aware of a separate issue. I guess using \tparam lets appear type parameters distinctively from method parameters, while now <S> shows up among the method parameters. Is that the issue you are talking about?

I cannot really tell because I never used \tparam and so far I did not use Doxygen with any other language than Java and Python. As far as I am concerned, it is perfectly fine for me to parse <S> from the method parameters in xml. It can easily be recognized as type parameter by the brackets.

@albert-github
Copy link
Collaborator

I think I was indeed thinking in the direction of C++ when mentioning the \tparam.
I was referring more to the <S> as parameter and its usage in java like mentioned in the link you provided. It look a bit as a template parameter (but my Java knowledge is insufficient to judge it correctly).
The mentioning of a separate issue was because the issue of this issue was the line break and the <S> in respect to \param is a separate issue and thus deserves a separate issue (now it probably will be ignored as it are just some side remarks in the original issue).

@Stewori
Copy link
Author

Stewori commented Apr 30, 2021

It look a bit as a template parameter (but my Java knowledge is insufficient to judge it correctly)

There are some subtle differences between Java generics and C++ templates (e.g. type erasure), but I think the overall concepts are similar enough to treat them equally in terms of documentation style. So, idealistically speaking I guess the right way would be to treat @param <S> (as apposed to non-bracket @param blah) in the same manner as \tparam S.

I am hesitating to file this as an issue because I don't really know how "this manner" actually looks like. Unless someone else is going to stand up and do this work, I will keep it in mind until I use doxygen with C++ code so I can naturally explore the behavior of \tparam. Eventually I will resume on that issue then, but cannot tell when this will be.

@Stewori
Copy link
Author

Stewori commented May 28, 2021

I happened to notice that this issue is not entirely fixed. The effects of a linebreak in @link are not that severe any more but they can cause a failing reference. Take that example:

public class Test {
    public void a(String s) {}

    public void a(String s, int i, float f) {}

    /**
     * {@link Test#a(String,
     * int, float) blah}
     */
    public void b() {}
}

Doxygen links the ref to public void a(String s) {} (or to nothing if not coincidentally a method exists that matches the args until the linebreak).
In xml one gets in b's detailed description:

        <detaileddescription>
<para><ref refid="classTest_1a16042b4f6e2d0a0a2618b7fda04b5d5f" kindref="member">int, float) blah</ref> </para>
        </detaileddescription>

example2.zip

albert-github added a commit to albert-github/doxygen that referenced this issue May 28, 2021
…g of subsequent doc

In this case we have a linebreak in the argument list, this is, for JAVA, not unreasonable.
@albert-github albert-github removed the fixed but not released Bug is fixed in github, but still needs to make its way to an official release label May 28, 2021
@albert-github
Copy link
Collaborator

This is a bit a different situation as the original problem was about the fact that the return was between the {@link and the target to be linked to.ow there is a return in the link itself, i.e. in the argument list.
I think that this is for JAVA not unreasonable, for normal links I'm a bit hesitant but when necessary it could be done in the same way (in that case only LINKMASK has to be changed to the version now used for JAVA (@doxygen I leave the decision to you).

I've just pushed a proposed patch, pull request #8573

@Stewori although a bit related issue has a different background and as the original issue was already merged it would have been better to create a new issue with, in this case, a reference to this issue)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants