1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00

generate javadoc from XML Documentation Comments

This commit is contained in:
Kevin Glynn 2011-07-26 10:07:11 +02:00
parent 0c6c57f855
commit 8c7965f04c
4 changed files with 168 additions and 3 deletions

View File

@ -132,6 +132,7 @@ namespace Twiglet.CS2J.Translator
.Add ("translator-timestamp-files=", v => cfg.TranslatorAddTimeStamp = Boolean.Parse(v))
.Add ("translator-blanket-throw=", v => cfg.TranslatorBlanketThrow = Boolean.Parse(v))
.Add ("translator-exception-is-throwable=", v => cfg.TranslatorExceptionIsThrowable = Boolean.Parse(v))
.Add ("translator-make-javadoc-comments=", v => cfg.TranslatorMakeJavadocComments = Boolean.Parse(v))
.Add ("experimental-enums-numericconsts", v => cfg.EnumsAsNumericConsts = true)
.Add ("experimental-unsigned-translatesigned", v => cfg.UnsignedNumbersToSigned = true)
.Add ("experimental-transforms=", v => cfg.ExperimentalTransforms = Boolean.Parse(v))

View File

@ -61,6 +61,11 @@ namespace Twiglet.CS2J.Translator
get; set;
}
public bool TranslatorMakeJavadocComments
{
get; set;
}
public bool EnumsAsNumericConsts
{
get; set;
@ -114,6 +119,7 @@ namespace Twiglet.CS2J.Translator
TranslatorAddTimeStamp = true;
TranslatorExceptionIsThrowable = false;
TranslatorBlanketThrow = true;
TranslatorMakeJavadocComments = true;
EnumsAsNumericConsts = false;
UnsignedNumbersToSigned = false;

View File

@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
using Antlr.Runtime.Tree;
using Antlr.Runtime;
@ -229,6 +232,94 @@ namespace Twiglet.CS2J.Translator.Transform
}
}
protected const string javaDocXslt = @"<?xml version=""1.0""?>
<xsl:stylesheet version=""1.0""
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""text""/>
<xsl:template match=""/"">
<xsl:apply-templates />
</xsl:template>
<xsl:template match=""c"">
{@code <xsl:value-of select="".""/>}
</xsl:template>
<xsl:template match=""code"">
{@code <xsl:value-of select="".""/>}
</xsl:template>
<xsl:template match=""b"">
<xsl:text>&lt;b></xsl:text><xsl:value-of select="".""/><xsl:text>&lt;/b></xsl:text>
</xsl:template>
<xsl:template match=""see"">
{@link #<xsl:value-of select=""@cref""/>}
</xsl:template>
<xsl:template match=""paramref"">
{@code <xsl:value-of select=""@name""/>}
</xsl:template>
<xsl:template match=""summary"">
<xsl:apply-templates />
</xsl:template>
<xsl:template match=""remarks"">
<xsl:apply-templates />
</xsl:template>
<xsl:template match=""example"">
<xsl:apply-templates />
</xsl:template>
<xsl:template match=""value"">
<xsl:apply-templates />
</xsl:template>
<xsl:template match=""param"">
@param <xsl:value-of select=""@name""/><xsl:text> </xsl:text> <xsl:apply-templates />
</xsl:template>
<xsl:template match=""exception"">
@throws <xsl:value-of select=""@cref""/><xsl:text> </xsl:text> <xsl:apply-templates />
</xsl:template>
<xsl:template match=""returns"">
@return <xsl:apply-templates />
</xsl:template>
<xsl:template match=""seealso"">
@see <xsl:value-of select=""@cref""/>
</xsl:template>
</xsl:stylesheet>";
private XslCompiledTransform _jdXslTrans = null;
protected XslCompiledTransform JdXslTrans
{
get
{
if (_jdXslTrans == null)
{
_jdXslTrans = new XslCompiledTransform();
// Encode the XML string in a UTF-8 byte array
byte[] encodedXsltString = Encoding.UTF8.GetBytes(javaDocXslt);
// Put the byte array into a stream and rewind it to the beginning
MemoryStream msXslt = new MemoryStream(encodedXsltString);
msXslt.Flush();
msXslt.Position = 0;
_jdXslTrans.Load(XmlReader.Create(msXslt));
}
return _jdXslTrans;
}
}
}
// Wraps a compilation unit with its imports search path

View File

@ -22,6 +22,9 @@ scope TypeContext {
@header
{
using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
@ -35,16 +38,80 @@ scope TypeContext {
// If top level is partial then this will contain the components so that we can mere with other parts down the line
public ClassDescriptorSerialized PartialDescriptor { get; set; }
private List<string> collectedComments = null;
protected string convertToJavaDoc(string docComment) {
string ret = null;
try {
StringBuilder javaDocStr = new StringBuilder();
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<root>" + docComment + "\n</root>";
// Encode the XML string in a UTF-8 byte array
byte[] encodedString = Encoding.UTF8.GetBytes(xml);
// Put the byte array into a stream and rewind it to the beginning
MemoryStream ms = new MemoryStream(encodedString);
ms.Flush();
ms.Position = 0;
// Build the XmlDocument from the MemorySteam of UTF-8 encoded bytes
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(ms);
JdXslTrans.Transform(xmlDoc,null,new StringWriter(javaDocStr));
ret = javaDocStr.ToString().Trim().Replace("\n", "\n* ");
ret = String.Format("/**\n* {0}\n*/", ret);
}
catch (Exception)
{
// skip, just return null
}
return ret;
}
private List<string> collectedComments = null;
List<string> CollectedComments {
get {
List<string> rets = new List<string>();
if (collectedComments != null) {
foreach (string c in collectedComments) {
rets.Add(processComment(c));
List<string> savedComments = new List<string>();
bool inDoc = false;
string xmlDoc = "";
foreach (string c in collectedComments) {
string line = processComment(c);
if (Cfg.TranslatorMakeJavadocComments && line.TrimStart().StartsWith("///")) {
inDoc = true;
savedComments.Add(line);
xmlDoc += line.TrimStart().Substring(3).TrimStart() + "\n";
}
else
{
if (inDoc) {
string javaDoc = convertToJavaDoc(xmlDoc);
if (javaDoc != null) {
rets.Add(javaDoc);
}
else {
rets.AddRange(savedComments);
}
savedComments = new List<string>();
inDoc = false;
xmlDoc = "";
}
rets.Add(line);
}
}
if (inDoc) {
string javaDoc = convertToJavaDoc(xmlDoc);
if (javaDoc != null) {
rets.Add(javaDoc);
}
else {
rets.AddRange(savedComments);
}
}
}
collectedComments = null;
return rets;