After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 795953 - PHP bug namespaces as return values
PHP bug namespaces as return values
Status: RESOLVED FIXED
Product: doxygen
Classification: Other
Component: documentation
1.8.14
Other Windows
: Normal normal
: ---
Assigned To: Dimitri van Heesch
Dimitri van Heesch
Depends on:
Blocks:
 
 
Reported: 2018-05-08 21:21 UTC by Magnus
Modified: 2018-05-09 18:03 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Direct SS from the doxygen file. (73.58 KB, image/png)
2018-05-08 21:21 UTC, Magnus
Details
doxygen config file and .php file. (25.19 KB, application/octet-stream)
2018-05-09 11:41 UTC, Magnus
Details
File containing a input filter, a .php file and a doxy config. (25.45 KB, application/octet-stream)
2018-05-09 13:43 UTC, Magnus
Details
.php, config and input filter files. (25.49 KB, application/octet-stream)
2018-05-09 15:04 UTC, Magnus
Details

Description Magnus 2018-05-08 21:21:50 UTC
Created attachment 371819 [details]
Direct SS from the doxygen file.

When I try to return a value that is part of a Namespace, say Namespace\Class Doxygen doesn't show it in the documentation page.

I'll attach an image of a function that is supposed to return such a type or null (PHP 7.1 feature).

Please note that this is a report for this bug only, the fact that some stuff isn't correctly linked to other namespaces will be matter for a future one.

You can write this sample and try to document the project.


Snippet:

<?php
namespace testNamespace;
class Class2
{
public function __construct()
{}
}

//-----------------------------------//

namespace mainNamespace;
class testClass
{
/**
* Func documentation.
* @param int Integer documentation.
* @return \testNamespace\Class2 Class2Documentation (it shows up).
**/
public function testFunc( int $int ): \testNamespace\Class2
{
  return new \testNamespace\Class2();
}
}
?>
Comment 1 albert 2018-05-09 08:01:43 UTC
I tried to reproduce your problem, but my picture looks a little bit different.

In the picture you have 3 boxes and I only see the last one in my output. Furthermore I see also some general differences in the outpt regarding the layout.
- Can you please attach a, small, self contained example (source+config file in a tar or zip) that allows us to reproduce the problem?

Furthermore doxygen gives some warnings:
.../aa.php:15: warning: argument 'int' of command @param is not found in the argument list of mainNamespace\testClass::testFunc(int $int)
.../aa.php:17: warning: Found unknown command `\testNamespace'
.../aa.php:17: warning: Found unknown command `\Class2'
.../aa.php:19: warning: The following parameters of mainNamespace\testClass\testFunc(int $int) are not documented:
  parameter '$int'


The problem with the parameter is that you specified the type (int) instead if the variable ($int), so the line should read:
* @param $int Integer documentation.

Regarding the 'unknown commands', doxygen sees the the \testNamespace and \Class2 as doxygen commands.
When using:
@return \\testNamespace::Class2 Class2Documentation (it shows up).
or
@return \\testNamespace#Class2 Class2Documentation (it shows up).
the links will show up.

(your first '\' will be outside the link and your second '`' will be shown as '::')
Comment 2 Magnus 2018-05-09 11:41:56 UTC
Created attachment 371837 [details]
doxygen config file and .php file.
Comment 3 Magnus 2018-05-09 11:42:14 UTC
Hi Albert, thanks for the quick answer.
Ah yes, I forgot to add the $int on the line: 
"* @param int Integer documentation."

It should now be, as you said:
"* @param int $int Integer documentation."

I've always used the '@param TYPE $var' style, it works like this in doxygen too.

I'm now attaching the Config file I was using for doxygen, as well as the .php file. 
P.S: on the filepath, I added a "FILEPATH" text, so try to search&replace that for your computer's path to the file.

But my main problem really is with the 'unknown commands'. Do you think I can add a input filter to solve this?
As for, in PHP, when resolving namespaces, you need to use the '\' to reach a class.
Comment 4 albert 2018-05-09 12:04:43 UTC
Regarding the real problem:
Do you mean that you need for another form of documentation that in the (doxygen) documentation part you need the '\'? In the code itself it is not a problem (I set SOURCE_BROWSER to YES)?
In case it is needed I think you can do something with a, complex, INPUT_FILTER (you only want to change the references in the documentation part) but it will be very hard.

Some side remarks.
- regarding TESTPATH I just removed the complete INPUT (as for test cases the file is anyway here) and I also unset the RECURSIVE
- the OUTPUT_DIRECTORY  gave some problems too (unset it as well).
Comment 5 Magnus 2018-05-09 13:14:08 UTC
Yes! I had to replace all '\' for '::' so that Doxy would refer correctly to all the classes in any namespace.
P.S: I believe that Doxygen doesn't support sub-namespaces as of now.
For example: 
'testNamespace::subNamespace::Class2' doesn't reference anything (even if it shows up).


But the main problem was solved. I've made it by using a quite simple PHP input_filter:

<?php
// Input
$source = file_get_contents($argv[1]);
// adds possibility to use '\' for namespaces
$regexp = '/\\\\/';
$replace = '::';
$source = preg_replace($regexp, $replace, $source);
?>

It worked for all my files on this lib now.
P.S2: Be aware for possible errors this may cause on one's code, though.

Hope it can help someone else!

Thanks a lot Albert.
Best regards.
Comment 6 Magnus 2018-05-09 13:15:59 UTC
@Edit I forgot to mark this as Solved, and to add the echo for the input_filter:

<?php
// Input
$source = file_get_contents($argv[1]);
// adds possibility to use '\' for namespaces
$regexp = '/\\\\/';
$replace = '::';
$source = preg_replace($regexp, $replace, $source);
// Output
echo $source;
?>
Comment 7 albert 2018-05-09 13:18:54 UTC
Can you give an example file with the 'testNamespace::subNamespace::Class2' so I can have a quick look?
Comment 8 Magnus 2018-05-09 13:43:29 UTC
Created attachment 371842 [details]
File containing a input filter, a .php file and a doxy config.

Ok, I've reproduced the subNamespaces error in this files.

Along with it, I've found a "bug" that happens when I use the Input_filter I suggested earlier:

When you have a class property (@var) and its type is a class of another namespace say, for example, '\outerNamespace\class' (this is how you access it on PHP), that input filter will convert it to '::outerNamespace::class', and this will cause the variable to be named incorrectly as '__pad0__'.

This error is also shown on this attachment.
Comment 9 albert 2018-05-09 14:00:59 UTC
The problem with the __pad0__ is in my opinion the wrong usage of @var, this should be:
        * @var $foo
        *   ::mainNamespace::testClass checking __pad0__
or (as it is directly above the variable:
        *   ::mainNamespace::testClass checking __pad0__

Regarding the problem with the subnamespace, I see this as well, have to investigate and therefore set the issue again to new / reopened
Comment 10 Magnus 2018-05-09 14:31:56 UTC
Actually, something very weird happened, it suddenly started working, even with the class name like it was. (I'm testing on my project files, but I've noticed there's some wrong things on the testing ones, too).

Oh, and if it's needed, I've added one more regxp in my input_filter, so these '::' before the namespace name can disappear. You just have to place this on top of the one I mentioned earlier.

// removes preceding '\' or '::' for the use of namespaces.
$regexp = '/ \\\\/';
$replace = ' ';
$source = preg_replace($regexp, $replace, $source);


Alright, glad I could help.
Comment 11 albert 2018-05-09 14:38:33 UTC
According to the documentation I found is the declaration of the subnamespace incorrect (see http://php.net/manual/en/language.namespaces.nested.php), this should be: 
    namespace testNamespace\subNamespace;

Note: during my tests I manually convert the '\' in the documentation to '::', so I'm not depending on a filter (even though the filter is necessary for non doxygen types of documentation generation).

Regarding the filter:
- does the filter rely on the fact that the doxygen commands in the documentation are all written with a '@'?
- is the source code correct (SOURCE_BROWSER = YES)?
Comment 12 Magnus 2018-05-09 15:04:13 UTC
Created attachment 371853 [details]
.php, config and input filter files.

Yes, you're correct. 
The referencing to any namespace has to be made directly (as in, doesn't matter where or how it is nested, you just have to reference the name of it, ignoring its 'parents').

About the filter:
- Yes, as is a commonly used way to document code in general, I made it so that all the commands (var, param, return, etc.) should be started with the '@' instead of the '\' command. But this can easily be tweaked on the regexp to accept any of them (or both).
- Yes, the source code shows correctly.

I'll attach the final version of the code/filter/config of the testing. (this one has source_browser = yes)
Comment 13 albert 2018-05-09 15:43:02 UTC
So the conclusion is all issues are solved and the replacement has to be done by a script / INPUT_FILTER.
Comment 14 Magnus 2018-05-09 15:50:21 UTC
Yes, all correlated problems were solved and a search&replace regex is enough to solve the problem.

I'm marking this as solved.

Thanks a lot for the help.