Comment Converter from C# to Java

Comment Converter is a small Java command-line utility that simplifies the task of converting C# XML comments into Javadoc format when porting C# source code to Java. The download package CommentConverter.zip contains the source code, a precompiled Java class file, a ReadMe file with usage instructions, and the two input/output samples shown below.

Comment Converter requires Java SE 8 and was compiled with Oracle Java SE 8u112. The utility was created by Christoph Nahr but is free to use, modify, and redistribute as you see fit. The rest of this page gives some technical background and provides details on functionality and limitations.

Comment Syntaxes

The feature set of C# XML comment tags is very similar to that of Javadoc comment tags but with some annoying syntactical differences:

  • C# XML comment blocks are usually identified by three slashes /// at the start of each line whereas Javadoc uses a slash followed by two asterisks /** on the first line, continued as a regular comment block. C# also supports the latter format but I have rarely seen it used, and never use it myself. Comment Converter only supports the three-slashes format.
  • C# XML comments always use XML tags for semantic information whereas Javadoc uses custom tags starting with @, sometimes also enclosed in curly braces ({@…}). There is a great deal of overlap between tag semantics but their syntax must be changed accordingly.

Conversion Process

While some manual editing will be required, the majority of the translation is a purely mechanical search-and-replace process. Given an input file, Comment Converter performs this translation as follows:

  1. Identify all input lines that begin with /// after an arbitrary amount of whitespace (or none).
  2. Copy all other input lines unmodified to the output. Comment Converter ignores their contents, so you can run it either on the original C# source code or on source code that has already been ported to Java, except for the C# XML comment blocks.
  3. For all input lines that begin with ///, store the exact sequence of leading whitespace (if any) on the first line of each consecutive block. Before the block, write an output line containing this sequence plus /**. After the block, write an output line containing this sequence plus ␣*/.
  4. For all input lines within a consecutive /// block, write an output line containing the stored whitespace sequence plus ␣* and the translation of the rest of the input line after ///.
  5. Special case: if the translated part contains only a single whitespace character (originally or due to deletions), the entire input line is dropped and no output line is written.

The following table shows how the translation is accomplished. Comment Converter loops through all specified C# XML comment fragments, processing longer fragments before shorter ones that are their exact prefixes. Any found fragment is deleted from the input line and the specified Javadoc replacement, if any, is inserted in its place.

C# XML Comment FragmentJavadoc Replacement
<exception@throws
<para><p>
</para></p>
<see@link
<c> {@code
<paramref
<typeparamref
<param @param
<typeparam
<returns> @return
<value>
"/> }
</c>
"> (deleted)
cref="
name="
</exception>
</param>
</returns>
<summary>
</summary>
</typeparam>
</value>
<code></code> (copied)
<example></example>
<include file="…" path="…"
<list></list>
<permission
</permission>
<remarks></remarks>
<seealso

Note that attributes (cref=, name=) are specified separately and simply deleted. This is necessary because C# XML comment blocks might well contain a line break between the XML comment element tag and its attribute, making line-by-line replacement of the complete element impossible.

A number of XML tags are passed through unchanged because they are already valid (code), Javadoc has no equivalent, or constructing the equivalent would be too complex. The exception is remarks which is left alone because this section usually appears at the bottom of a C# XML comment block. In the Javadoc output, it designates the lines that you want to move to the top, below the summary line.

In addition to these tag conversions, Comment Converter also translates a number of commonly used exception class names to their closest equivalents. These are sufficiently long and distinctive that there should be no false positives.

C# Exception NameJavadoc Replacement
ArgumentExceptionIllegalArgumentException
ArgumentNullExceptionNullPointerException
ArgumentOutOfRangeExceptionIndexOutOfBoundsException
AssertionExceptionAssertionError
DivideByZeroExceptionArithmeticException
FormatExceptionNumberFormatException
IndexOutOfRangeExceptionIndexOutOfBoundsException
InvalidCastExceptionClassCastException
InvalidEnumArgumentExceptionEnumConstantNotPresentException
InvalidOperationExceptionIllegalStateException
KeyNotFoundExceptionIllegalArgumentException
NotImplementedExceptionUnsupportedOperationException
ObjectDisposedExceptionIllegalStateException
OverflowExceptionArithmeticException

Conversion Sample

The following code shows a (nonsensical) C# XML comment block that includes all the tags for which Comment Converter provides a translation, as well as a common one (remarks) for which it doesn’t. This sample is also included in the download package.

/// <summary>Summary description.</summary>
/// <typeparam name="T">The type of all elements.</typeparam>
/// <param name="args">The arguments for the method.</param>
/// <returns>The value returned by the method.</returns>
/// <value>The value of the property.</value>
/// <exception cref="ArgumentNullException">
/// <paramref name="args"/> is <c>null</c>.</exception>
/// <remarks>
/// Type <typeparamref name="T"/> is the type of all elements.
/// <para>See <see cref="SomeMethod"/> for details.</para>
/// </remarks>

Comment Converter produces the following output for this block:

/**
 * Summary description.
 * @param T The type of all elements.
 * @param args The arguments for the method.
 * @return The value returned by the method.
 * @return The value of the property.
 * @throws NullPointerException 
 * {@code args} is {@code null}.
 * <remarks>
 * Type {@code T} is the type of all elements.
 * <p>See {@link SomeMethod} for details.</p>
 * </remarks>
 */

This looks pretty good, but as you can see some manual editing still required:

  • Type parameters (T) are not surrounded by <…> which you must add manually.
  • Code links use C# syntax, i.e. capitalized and without a leading # for members.
  • C# properties combine getter and setter. Java requires two separate methods, so you must create one Javadoc comment for each and selectively copy the conversion results.
  • The contents of the remarks section must be moved up, below the summary description.
  • The writing style may differ from Javadoc standards. Descriptions start with capitalized words and end with a period, and exception documentation does not include a leading “if.”
  • The summary description may contain multiple full sentences (not shown here). In that case you will have to rewrite them in some way that makes sense.

More effort will be needed to convert unsupported tags, especially complex list structures. By and large, though, Comment Converter should save a lot of time when porting from C# to Java.