Bug 322409 (MONO79706) - [GMCS] /doc doesn't like generic types
Summary: [GMCS] /doc doesn't like generic types
Status: RESOLVED FIXED
Alias: MONO79706
Product: Mono: Compilers
Classification: Mono
Component: C# (show other bugs)
Version: 1.1
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Atsushi Enomoto
QA Contact: Mono Bugs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-10-20 14:38 UTC by Jonathan Pryor
Modified: 2007-09-15 21:24 UTC (History)
0 users

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
gendoc.cs (849 bytes, text/plain)
2006-10-20 14:40 UTC, Thomas Wiest
Details
CSC.EXE /doc output of gendoc.cs (1.23 KB, text/plain)
2006-10-20 17:40 UTC, Thomas Wiest
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Wiest 2007-09-15 20:13:32 UTC


---- Reported by jonpryor@vt.edu 2006-10-20 07:38:29 MST ----

Please fill in this template when reporting a bug, unless you know what you
are doing.
Description of Problem:

gmcs /doc doesn't properly support generic types & members.

Take the following code:

	// gmcs documents generic members incorrectly
	using System.Collections.Generic;

	namespace Test {
		/// <remarks>T:Test.DocMe</remarks>
		/// <seealso cref="T:Test.DocMe`1" />
		class DocMe {

			///
<remarks>M:Test.DocMe.UseList(System.Collections.Generic.List{System.Int32})</remarks>
			public static void UseList (List<int> list) {}

			/// <remarks>M:Test.DocMe.Main</remarks>
			public static void Main ()
			{
			}
		}

		/// <remarks>T:Test.DocMe`1</remarks>
		class DocMe<T> {
			///
<remarks>M:Test.DocMe`1.UseList(System.Collections.Generic.List{`0})</remarks>
			public void UseList (List<T> list) {}

			///
<remarks>M:Test.DocMe`1.UseList`1(System.Collections.Generic.List{``0})</remarks>
			public void UseList<U> (List<U> list) {}

			/// <remarks>M:Test.DocMe`1.RefMethod`1(`0@,``0@)</remarks>
			public void RefMethod<U> (ref T t, ref U u) {}
		}
	}

Compile the aboce code with: gmcs /doc:gendoc.xml gendoc.cs

There are three problems with `gmcs /doc' support for the above code:

1. It generates a warning CS1584 for the <seealso cref="T:Test.DocMe`1"/>.
 AFAIK, this is a valid cref, so a warning should not be generated. 
(Furthermore, within the xml the T:Test.DocMe`1 becomes !:Test.DocMe`1 --
an error prefix -- and this shouldn't happen either.)

2. It generates an error CS1569 "Error generating XML documentation file
`gendoc.xml' (`Object reference not set to an instance of an object')"
(i.e. an internal NullReferenceException) when attempting to handle
M:Test.DocMe`1.RefMethod`1.  Remove the comment on RefMethod<U>() and it
will generate documentation normally, but this shouldn't happen.

3. Once (2) is fixed (or the RefMethod comment is removed), look at the
generated gendoc.xml.  It has incorrect member string IDs.  (The doc
comments include the "correct" XML IDs.)  See also Ecma-334 3rd edition,
Annex E (in particular, E.3.1, the final "bullet" which begins "For methods
and properties with arguments, the argument list follows...".

For example, with the member:

	public static void UseList (List<int> list) {}

the string ID generated is:

        <member
name="M:Test.DocMe.UseList(System.Collections.Generic.List`1[[System.Int32,
mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]])">

It *should* be:

        <member
name="M:Test.DocMe.UseList(System.Collections.Generic.List{System.Int32})">

Similarly, for:

	public void UseList (List<T> list) {}

The string ID generated is:

        <member
name="M:Test.DocMe`1.UseList(System.Collections.Generic.List`1[T])">

It *should* be:

        <member
name="M:Test.DocMe`1.UseList(System.Collections.Generic.List{`0})">

(as per Annex E.3.1).
 
Finally, if I understand Annex E properly, the compiler should support
replacing type parameters with the type position within ID strings.

For example, a <see cref="M:Test.DocMe{T}.UseList(List{T})/> reference
within the .cs file would need to be transformed into a <see
cref="M:Test.DocMe`1.UseList(System.Collections.Generic.List{`0})"/> (in
which T is replaced with `0).

For good measure, this should all be verified against CSC 2.0 (I don't have
any access to it), but from my understanding of Annex E this should all be
correct.



---- Additional Comments From jonpryor@vt.edu 2006-10-20 07:40:23 MST ----

Created an attachment (id=170685)
gendoc.cs




---- Additional Comments From jonpryor@vt.edu 2006-10-20 07:40:59 MST ----

Attached the actual file so that line wrapping issues aren't a
hindrence (those comments are too wide).



---- Additional Comments From jonpryor@vt.edu 2006-10-20 10:40:12 MST ----

Created an attachment (id=170686)
CSC.EXE /doc output of gendoc.cs




---- Additional Comments From jonpryor@vt.edu 2006-10-20 10:46:51 MST ----

There is one oddity here: CSC.EXE behavior differs from Ecma-334, so
I'm not sure which is correct.

The difference is in generic methods, e.g.

	public void UseList<U> (List<U> list) {}

Ecma-334 suggests that the name of this should be:

	M:Test.DocMe`1.UseList`1(System.Collections.Generic.List{``0})

See annex E.3.2 "ID string examples", the Methods bullet, in which:

	public MyList<T> GetValues<T>(T value) { … }

becomes:

	"M:Acme.UseList.getValues`1(``0)"

However, CSC 2.0 generates:

       M:Test.DocMe`1.UseList``1(System.Collections.Generic.List{``0})

Note the extra ` in the method name, UseList`1 vs. UseList``1.

Does anyone know which is correct?  Or is "whatever CSC does" the
correct output?



---- Additional Comments From miguel@ximian.com 2007-01-01 03:48:36 MST ----

Lets go with CSC as the reference in this case



---- Additional Comments From mike.allen@durrusa.com 2007-05-02 12:54:02 MST ----

*** https://bugzilla.novell.com/show_bug.cgi?id=MONO81513 has been marked as a duplicate of this bug. ***



---- Additional Comments From mike.allen@durrusa.com 2007-05-02 13:04:50 MST ----

Can I just raise one additional related issue?  gmcs produces a CS1580
error when it encounters a cref attribute identifying a function that
takes a generic argument.

For example:

namespace Test
{

    /// <summary>Test.</summary>
    ///
    /// <remarks>Don't forget to <see cref="DoSomething (T)" />!</remarks>
    /// <typeparam name="T">Some type.</typeparam>

    public class Test <T>
    {

        /// <summary>Some function.</summary>
        ///
        /// <param name="someValue">Whatever.</param>

        public void DoSomething (T someValue)
        {
        }
    }
}

Produces the message:

test.cs(9,18): error CS1580: Invalid type for parameter `1' in XML
comment cref attribute `DoSomething (T)'
Compilation failed: 1 error(s), 0 warnings

This compiles OK with the MS compiler.



---- Additional Comments From atsushi@ximian.com 2007-07-18 12:09:04 MST ----

Fixed in svn.

Imported an attachment (id=170685)
Imported an attachment (id=170686)

Unknown operating system unknown. Setting to default OS "Other".