<html>
<head>
<style><!--
  body {background-color:#ffffff;}
  .file {border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;}
  .pathname {font-family:monospace; float:right;}
  .fileheader {margin-bottom:.5em;}
  .diff {margin:0;}
  .tasklist {padding:4px;border:1px dashed #000000;margin-top:1em;}
  .tasklist ul {margin-top:0;margin-bottom:0;}
  tr.alt {background-color:#eeeeee}
  #added {background-color:#ddffdd;}
  #addedchars {background-color:#99ff99;font-weight:bolder;}
  tr.alt #added {background-color:#ccf7cc;}
  #removed {background-color:#ffdddd;}
  #removedchars {background-color:#ff9999;font-weight:bolder;}
  tr.alt #removed {background-color:#f7cccc;}
  #copied {background-color:#ccccff;}
  tr.alt #copied {background-color:#bbbbf7;}
  #info {color:#888888;}
  #context {background-color:#eeeeee;}
  td {padding-left:.3em;padding-right:.3em;}
  tr.head {border-bottom-width:1px;border-bottom-style:solid;}
  tr.head td {padding:0;padding-top:.2em;}
  .task {background-color:#ffff00;}
  .comment {white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd}
  .error {color:red;}
  hr {border-width:0px;height:2px;background:black;}
--></style>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head"><td colspan="5">Commit in <b><tt>metaas/trunk/src</tt></b></td></tr>
<tr><td><tt>main/antlr/uk/co/badgersinfoil/metaas/impl/parser/javadoc/<a href="#file1"><span id="added">Javadoc.g</span></a></tt> </td><td></td><td align="right" id="added">+133</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr class="alt"><td><tt>main/java/uk/co/badgersinfoil/metaas/dom/<a href="#file2">ASArg.java</a></tt> </td><td></td><td align="right" id="added">+3</td><td></td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file3"><span id="added">DocComment.java</span></a></tt> </td><td></td><td align="right" id="added">+24</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file4"><span id="added">DocTag.java</span></a></tt> </td><td></td><td align="right" id="added">+12</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file5">Documentable.java</a></tt> </td><td></td><td align="right" id="added">+45</td><td align="right" id="removed">-9</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr class="alt"><td><tt>main/java/uk/co/badgersinfoil/metaas/impl/<a href="#file6">ASTASArg.java</a></tt> </td><td></td><td align="right" id="added">+27</td><td align="right" id="removed">-1</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file7">ASTASField.java</a></tt> </td><td></td><td></td><td align="right" id="removed">-8</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file8">ASTASMember.java</a></tt> </td><td></td><td align="right" id="added">+22</td><td align="right" id="removed">-3</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file9">ASTASMethod.java</a></tt> </td><td></td><td></td><td align="right" id="removed">-9</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file10">ASTASType.java</a></tt> </td><td></td><td align="right" id="added">+16</td><td align="right" id="removed">-4</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file11"><span id="added">ASTDocComment.java</span></a></tt> </td><td></td><td align="right" id="added">+74</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file12"><span id="added">ASTDocTag.java</span></a></tt> </td><td></td><td align="right" id="added">+43</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file13">ASTUtils.java</a></tt> </td><td></td><td align="right" id="added">+7</td><td align="right" id="removed">-1</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr class="alt"><td><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/<a href="#file14">DocCommentUtils.java</a></tt> </td><td></td><td align="right" id="added">+208</td><td align="right" id="removed">-11</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr><td><tt>test/java/uk/co/badgersinfoil/metaas/<a href="#file15">DocCommentTests.java</a></tt> </td><td></td><td align="right" id="added">+55</td><td align="right" id="removed">-3</td><td nowrap="nowrap" align="center">428 -&gt; 429</td></tr>
<tr class="alt"><td><tt>test/java/uk/co/badgersinfoil/metaas/impl/parser/javadoc/<a href="#file16"><span id="added">JavadocParserTests.java</span></a></tt> </td><td></td><td align="right" id="added">+75</td><td></td><td nowrap="nowrap" align="right">added 429</td></tr>
<tr><td></td><td></td><td align="right" id="added">+744</td><td align="right" id="removed">-49</td><td></td></tr>
</table>
<small id="info">6 added + 10 modified, total 16 files</small><br />
<div class="tasklist"><ul>
<li><a href="#task1">TODO: match document line-ending format</a></li>
<li><a href="#task2">TODO: use the original line-ending format</a></li>
<li><a href="#task3">TODO: try harder to find the right place/line to
</a></li>
<li><a href="#task4">TODO: use the original line-ending format
</a></li>
<li><a href="#task5">TODO: use document existing end-of-line format
</a></li>
</ul></div>
<pre class="comment">
first cut of improved javadoc handling APIs
</pre>
<hr /><a name="file1" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/main/antlr/uk/co/badgersinfoil/metaas/impl/parser/javadoc</span><br />
<div class="fileheader" id="added"><big><b>Javadoc.g</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/antlr/uk/co/badgersinfoil/metaas/impl/parser/javadoc/Javadoc.g        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/antlr/uk/co/badgersinfoil/metaas/impl/parser/javadoc/Javadoc.g        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,133 @@
</small></pre><pre class="diff" id="added">+/*
+ * Copyright (c) 2007 David Holroyd
+ */
+
+grammar Javadoc;
+
+
+options {
+        k = 4;
+        output=AST;
+        ASTLabelType=LinkedListTree;
+}
+
+tokens {
+        JAVADOC;
+        INLINE_TAG;
+        DESCRIPTION;
+        PARA_TAG;
+        TEXT_LINE;
+}
+
+@parser::header {
+package uk.co.badgersinfoil.metaas.impl.parser.javadoc;
+
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
+import uk.co.badgersinfoil.metaas.impl.TokenBuilder;
+}
+
+@lexer::header {
+package uk.co.badgersinfoil.metaas.impl.parser.javadoc;
+}
+
+// disable standard error handling; be strict
+@rulecatch { }
+
+@parser::members {
+        protected void mismatch(IntStream input, int ttype, BitSet follow)
+                throws RecognitionException
+        {
+                throw new MismatchedTokenException(ttype, input);
+        }
+
+        private void placeholder(LinkedListTree imaginary) {
+                if (imaginary.getChildCount() &gt; 0) {
+                        return;
+                }
+
+                LinkedListToken tok = (LinkedListToken)input.LT(1);
+                LinkedListToken placeholder = TokenBuilder.newPlaceholder();
+                tok.beforeInsert(placeholder);
+                imaginary.setStartToken(placeholder);
+                imaginary.setStopToken(placeholder);
+        }
+
+}
+@lexer::members {
+        protected void mismatch(IntStream input, int ttype, BitSet follow)
+                throws RecognitionException
+        {
+                throw new MismatchedTokenException(ttype, input);
+        }
+}
+
+
+comment_body
+        :        d=description {placeholder($d.tree);}
+                paragraph_tag*
+                EOF
+                -&gt; ^(JAVADOC description paragraph_tag*)
+        
+
+description
+        :        text_line*
+                -&gt; ^(DESCRIPTION text_line*)
+        
+
+text_line
+        :        text_line_start
+                text_line_content*
+                (NL | EOF!)
+        |        NL
+        
+
+text_line_start
+        :        (LBRACE ATWORD)=&gt; inline_tag
+        |        WORD | STARS | WS | LBRACE | RBRACE | AT
+        
+
+text_line_content
+        :        (LBRACE ATWORD)=&gt; inline_tag
+        |        WORD | STARS | WS | LBRACE | RBRACE | AT | ATWORD
+        
+
+inline_tag
+        :        LBRACE ATWORD inline_tag_content* RBRACE
+                -&gt; ^(INLINE_TAG ATWORD inline_tag_content*)
+        
+
+inline_tag_content
+        :        WORD | STARS | WS | AT | NL
+        
+
+paragraph_tag
+        :        ATWORD text_line_content*
+                (        NL text_line*
+                |        EOF
+                )
+                -&gt; ^(PARA_TAG ATWORD text_line_content* NL? text_line*)
+        
+
+
+STARS:                '*'+;
+
+LBRACE:                '{';
+RBRACE:                '}';
+AT:                '@';
+
+WS:                (' ' | '\t')+;
+
+NL
+options {
+        k=*;
+}
+        :                ('\r\n' | '\r' | '\n') WS? (STARS WS?)?;
+
+ATWORD:                '@' WORD WORD_TAIL;
+
+WORD:                ~('\n' | ' ' | '\r' | '\t' | '{' | '}' | '@')
+                WORD_TAIL;
+
+fragment
+WORD_TAIL:        (~('\n' | ' ' | '\r' | '\t' | '{' | '}'))*;
</pre></div>
<hr /><a name="file2" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/dom</span><br />
<div class="fileheader"><big><b>ASArg.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/ASArg.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/ASArg.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -43,4 +43,7 @@
</small></pre><pre class="diff" id="context">          * list of a function or method.
          */
         public boolean isRest();
</pre><pre class="diff" id="added">+
+        public String getDescriptionString();
+        public void setDescription(String description);
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file3" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/dom</span><br />
<div class="fileheader" id="added"><big><b>DocComment.java</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/DocComment.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/DocComment.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,24 @@
</small></pre><pre class="diff" id="added">+/**
+ * ASDocComment.java
+ * 
+ * Copyright (c) 2007 David Holroyd
+ */
+
+package uk.co.badgersinfoil.metaas.dom;
+
+import java.util.Iterator;
+
+public interface DocComment {
+
+        public String getDescriptionString();
+
+        public void setDescriptionString(String description);
+
+        public Iterator findTags(String string);
+
+        public void addParaTag(String name, String body);
+
+        public void setDocComment(String text);
+
+        public String getDocCommentString();
+}
</pre></div>
<hr /><a name="file4" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/dom</span><br />
<div class="fileheader" id="added"><big><b>DocTag.java</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/DocTag.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/DocTag.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,12 @@
</small></pre><pre class="diff" id="added">+/**
+ * ASTDocTag.java
+ *
+ * Copyright (c) 2007 David Holroyd
+ */
+
+package uk.co.badgersinfoil.metaas.dom;
+
+public interface DocTag {
+
+        public String getBodyString();
+}
</pre></div>
<hr /><a name="file5" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/dom</span><br />
<div class="fileheader"><big><b>Documentable.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/Documentable.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/dom/Documentable.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -1,3 +1,9 @@
</small></pre><pre class="diff" id="added">+/**
+ * Documentable.java
+ * 
+ * Copyright (c) 2006-2007 David Holroyd
+ */
+
</pre><pre class="diff" id="context"> package uk.co.badgersinfoil.metaas.dom;
 
 /**
</pre><pre class="diff"><small id="info">@@ -3,19 +9,13 @@
</small></pre><pre class="diff" id="context">  * Interface for parts of the ActionScript source code which can have API
  * documentation comments attached.
</pre><pre class="diff" id="removed">- * 
- * [Hopefully this interface will be extended to allow more sophisticated
- * JavaDoc-style comment processing.]
</pre><pre class="diff" id="context">  */
 public interface Documentable {
 
         /**
</pre><pre class="diff" id="removed">-         * Returns the contents of the documentation comment for this API
-         * element.
-         * Lines of text in the comment will alreeady have had leading '*'
-         * characters removed.  If there is no current documentation comment,
-         * null will be returned.
</pre><pre class="diff" id="added">+         * @deprecated use {@link #getDescriptionString()} or
+         *             {@link #getDocumentation()} instead.
</pre><pre class="diff" id="context">          */
         public String getDocComment();
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="added">+        
</pre><pre class="diff" id="context">         /**
          * Set the contents of the 'documentation comment' for this ActionScript
</pre><pre class="diff"><small id="info">@@ -24,6 +24,42 @@
</small></pre><pre class="diff" id="context">          * have initial indentation and a '*' character added, so you shouldn't
          * include these in the text yourself.  Supplying a null value removes
          * any existing comment.
</pre><pre class="diff" id="added">+         * 
+         * @throws SyntaxException if the given text contains an end-of-comment
+         *         marker
+         * @deprecated use {@link #setDescription(String)} or
+         *             {@link #getDocumentation()} instead.
</pre><pre class="diff" id="context">          */
         public void setDocComment(String text);
</pre><pre class="diff" id="added">+
+        /**
+         * Returns the 'description' part of this documentation comment as
+         * a string.  The description is the comment text from the start of
+         * the comment up to the first 'tagged paragraph'.
+         * 
+         * &lt;p&gt;This method is a shortcut for
+         * &lt;code&gt;getDocumentation().getDescriptionString()&lt;/code&gt;.&lt;/p&gt;
+         */
+        public String getDescriptionString();
+
+        /**
+         * Defines the 'description' part of the documentation comment of this
+         * API element.
+         * 
+         * &lt;p&gt;This method is a shortcut for
+         * &lt;code&gt;getDocumentation().setDescription(description)&lt;/code&gt;.&lt;/p&gt;
+         * 
+         * @throws SyntaxException if the given text contains an end-of-comment
+         *         marker, or a tagged-paragraph
+         */
+        public void setDescription(String description);
+
+        /**
+         * Returns a reference to an object allowing manipulation of
+         * documentation associated with this Documentable API element.  If
+         * there is currently no documentation available, this method will
+         * return an 'empty' object, but modifications to that object will
+         * cause a documentation-comment to be created in the source code.
+         */
+        public DocComment getDocumentation();
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file6" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTASArg.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASArg.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASArg.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -6,10 +6,13 @@
</small></pre><pre class="diff" id="context"> 
 package uk.co.badgersinfoil.metaas.impl;
 
</pre><pre class="diff" id="added">+import java.util.Iterator;
</pre><pre class="diff" id="context"> import org.asdt.core.internal.antlr.AS3Parser;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.SyntaxException;
 import uk.co.badgersinfoil.metaas.dom.ASArg;
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.DocComment;
+import uk.co.badgersinfoil.metaas.dom.ASMethod;
+import uk.co.badgersinfoil.metaas.dom.DocTag;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
 
 
</pre><pre class="diff"><small id="info">@@ -87,4 +90,27 @@
</small></pre><pre class="diff" id="context">         public boolean isRest() {
                 return ast.getFirstChild().getType() == AS3Parser.REST;
         }
</pre><pre class="diff" id="added">+
+        public String getDescriptionString() {
+                DocComment doc = getMethod().getDocumentation();
+                String name = getName();
+                DocTag tag = DocCommentUtils.findParam(doc, name);
+                if (tag == null) {
+                        return null;
+                }
+                return tag.getBodyString().substring(name.length()+1);
+        }
+
+        public void setDescription(String description) {
+                DocComment doc = getMethod().getDocumentation();
+                String name = getName();
+                DocTag tag = DocCommentUtils.findParam(doc, name);
+                if (tag == null) {
+                        doc.addParaTag("param", name+" "+description);
+                }
+        }
+
+        private ASMethod getMethod() {
+                return new ASTASMethod(ast.getParent().getParent());
+        }
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file7" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTASField.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASField.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASField.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -47,14 +47,6 @@
</small></pre><pre class="diff" id="context">                 init.addChildWithTokens(exp);
         }
 
</pre><pre class="diff" id="removed">-        public String getDocComment() {
-                return DocCommentUtils.getDocComment(ast);
-        }
-
-        public void setDocComment(String text) {
-                DocCommentUtils.setDocComment(ast, text);
-        }
-
</pre><pre class="diff" id="context">         public boolean isConst() {
                 return ast.getChild(INDEX_DEF).getType() == AS3Parser.CONST;
         }
</pre></div>
<hr /><a name="file8" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTASMember.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASMember.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASMember.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -7,9 +7,8 @@
</small></pre><pre class="diff" id="context"> package uk.co.badgersinfoil.metaas.impl;
 
 import java.util.List;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="context"> import org.asdt.core.internal.antlr.AS3Parser;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.DocComment;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.dom.ASMember;
 import uk.co.badgersinfoil.metaas.dom.ASMetaTag;
 import uk.co.badgersinfoil.metaas.dom.Visibility;
</pre><pre class="diff"><small id="info">@@ -81,4 +80,24 @@
</small></pre><pre class="diff" id="context">         public ASMetaTag newMetaTag(String name) {
                 return TagUtils.newMetaTag(ast, name);
         }
</pre><pre class="diff" id="removed">-}
</pre><pre class="diff" id="added">+
+        public void setDocComment(String text) {
+                getDocumentation().setDocComment(text);
+        }
+
+        public String getDocComment() {
+                return getDocumentation().getDocCommentString();
+        }
+
+        public String getDescriptionString() {
+                return getDocumentation().getDescriptionString();
+        }
+
+        public void setDescription(String description) {
+                getDocumentation().setDescriptionString(description);
+        }
+
+        public DocComment getDocumentation() {
+                return DocCommentUtils.createDocComment(ast);
+        }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file9" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTASMethod.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASMethod.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASMethod.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -253,13 +253,4 @@
</small></pre><pre class="diff" id="context">         public List getStatementList() {
                 return stmtList.getStatementList();
         }
</pre><pre class="diff" id="removed">-
-        public String getDocComment() {
-                return DocCommentUtils.getDocComment(ast);
-        }
-
-
-        public void setDocComment(String text) {
-                DocCommentUtils.setDocComment(ast, text);
-        }
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file10" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTASType.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASType.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTASType.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -10,7 +10,7 @@
</small></pre><pre class="diff" id="context"> import java.util.LinkedList;
 import java.util.List;
 import org.asdt.core.internal.antlr.AS3Parser;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.DocComment;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.dom.ASMetaTag;
 import uk.co.badgersinfoil.metaas.dom.ASMethod;
 import uk.co.badgersinfoil.metaas.dom.ASType;
</pre><pre class="diff"><small id="info">@@ -88,14 +88,26 @@
</small></pre><pre class="diff" id="context">                 return ASTUtils.findChildByType(ast, AS3Parser.TYPE_BLOCK);
         }
 
</pre><pre class="diff" id="added">+        public void setDocComment(String text) {
+                getDocumentation().setDocComment(text);
+        }
+
</pre><pre class="diff" id="context">         public String getDocComment() {
</pre><pre class="diff" id="removed">-                return DocCommentUtils.getDocComment(ast);
</pre><pre class="diff" id="added">+                return getDocumentation().getDocCommentString();
</pre><pre class="diff" id="context">         }
 
</pre><pre class="diff" id="removed">-        public void setDocComment(String text) {
-                DocCommentUtils.setDocComment(ast, text);
</pre><pre class="diff" id="added">+        public String getDescriptionString() {
+                return getDocumentation().getDescriptionString();
</pre><pre class="diff" id="context">         }
 
</pre><pre class="diff" id="added">+        public void setDescription(String description) {
+                getDocumentation().setDescriptionString(description);
+        }
+
+        public DocComment getDocumentation() {
+                return DocCommentUtils.createDocComment(ast);
+        }
+
</pre><pre class="diff" id="context">         public Visibility getVisibility() {
                 return ModifierUtils.getVisibility(findModifiers());
         }
</pre></div>
<hr /><a name="file11" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader" id="added"><big><b>ASTDocComment.java</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTDocComment.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTDocComment.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,74 @@
</small></pre><pre class="diff" id="added">+/**
+ * ASTASDocComment.java
+ *
+ * Copyright (c) 2007 David Holroyd
+ */
+
+package uk.co.badgersinfoil.metaas.impl;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import uk.co.badgersinfoil.metaas.dom.DocComment;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
+import uk.co.badgersinfoil.metaas.impl.parser.javadoc.JavadocParser;
+
+
+public class ASTDocComment implements DocComment {
+
+        private LinkedListTree ast;
+        private LinkedListTree javadoc;
+
+        public ASTDocComment(LinkedListTree ast) {
+                this.ast = ast;
+                javadoc = DocCommentUtils.buildJavadoc(ast);
+        }
+
+        public String getDescriptionString() {
+                return DocCommentUtils.getDescriptionString(ast);
+        }
+
+        public void setDescriptionString(String description) {
+                DocCommentUtils.setDescriptionString(ast, description);
+        }
+
+        public Iterator findTags(String name) {
+                if (javadoc == null) {
+                        return Collections.EMPTY_LIST.iterator();
+                }
+                String tagname = "@" + name;
+                LinkedList tags = new LinkedList();
+                ASTIterator i = new ASTIterator(javadoc);
+                LinkedListTree para;
+                while ((para=i.search(JavadocParser.PARA_TAG)) != null) {
+                        LinkedListTree tag = para.getFirstChild();
+                        if (tag.getText().equals(tagname)) {
+                                tags.add(new ASTDocTag(para));
+                        }
+                }
+                return tags.iterator();
+        }
+
+        public void addParaTag(String name, String body) {
+                String newline = DocCommentUtils.getNewlineText(ast, javadoc);
+                body = body.replaceAll("\n", newline);
+                if (javadoc == null) {
+                        DocCommentUtils.setDocComment(ast, "\n @"+name+" "+body+"\n");
+                        javadoc = DocCommentUtils.buildJavadoc(ast);
+                } else {
+                        String comment = DocCommentUtils.getDocComment(ast);
+                        if (!comment.endsWith("\n")) {
<a name="task1" />+                                comment += "\n";  // <span class="task">TODO</span>: match document line-ending format
+                        }
+                        DocCommentUtils.setDocComment(ast, comment + "@"+name+" "+body);
+                }
+        }
+
+        public String getDocCommentString() {
+                return DocCommentUtils.getDocComment(ast);
+        }
+
+        public void setDocComment(String text) {
+                DocCommentUtils.setDocComment(ast, text);
+        }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file12" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader" id="added"><big><b>ASTDocTag.java</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTDocTag.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTDocTag.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,43 @@
</small></pre><pre class="diff" id="added">+/**
+ * ASTDocTag.java
+ *
+ * Copyright (c) 2007 David Holroyd
+ */
+
+package uk.co.badgersinfoil.metaas.impl;
+
+import uk.co.badgersinfoil.metaas.dom.DocTag;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
+import uk.co.badgersinfoil.metaas.impl.parser.javadoc.JavadocParser;
+
+
+public class ASTDocTag implements DocTag {
+
+        private LinkedListTree ast;
+
+        public ASTDocTag(LinkedListTree ast) {
+                this.ast = ast;
+        }
+
+        public String getBodyString() {
+                StringBuffer result = new StringBuffer();
+                for (LinkedListToken tok=ast.getStartToken().getNext(); tok!=null&amp;&amp;tok.getType()!=-1; tok=tok.getNext()) {
+                        result.append(stringify(tok));
+                        if (tok == ast.getStopToken()) {
+                                break;
+                        }
+                }
+                return result.toString();
+        }
+
+        private static String stringify(LinkedListToken tok) {
+                switch (tok.getType()) {
+                        case JavadocParser.NL:
<a name="task2" />+                                // <span class="task">TODO</span>: use the original line-ending format
+                                return "\n";
+                        default:
+                                return tok.getText();
+                }
+        }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file13" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>ASTUtils.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTUtils.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/ASTUtils.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -414,7 +414,7 @@
</small></pre><pre class="diff" id="context">         
         public static String stringifyNode(LinkedListTree ast) {
                 StringBuffer result = new StringBuffer();
</pre><pre class="diff" id="removed">-                for (LinkedListToken tok=ast.getStartToken(); tok!=null; tok=tok.getNext()) {
</pre><pre class="diff" id="added">+                for (LinkedListToken tok=ast.getStartToken(); tok!=null<span id="addedchars">&amp;&amp;tok.getType()!=-1</span>; tok=tok.getNext()) {
</pre><pre class="diff" id="context">                         result.append(tok.getText());
                         if (tok == ast.getStopToken()) {
                                 break;
</pre><pre class="diff"><small id="info">@@ -422,4 +422,10 @@
</small></pre><pre class="diff" id="context">                 }
                 return result.toString();
         }
</pre><pre class="diff" id="added">+
+        public static void deleteAllChildren(LinkedListTree ast) {
+                while (ast.getChildCount() &gt; 0) {
+                        ast.deleteChild(0);
+                }
+        }
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file14" /><div class="file">
<span class="pathname">metaas/trunk/src/main/java/uk/co/badgersinfoil/metaas/impl</span><br />
<div class="fileheader"><big><b>DocCommentUtils.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/DocCommentUtils.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/main/java/uk/co/badgersinfoil/metaas/impl/DocCommentUtils.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -6,17 +6,32 @@
</small></pre><pre class="diff" id="context"> 
 package uk.co.badgersinfoil.metaas.impl;
 
</pre><pre class="diff" id="added">+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.regex.Pattern;
+import org.antlr.runtime.ANTLRReaderStream;
+import org.antlr.runtime.RecognitionException;
</pre><pre class="diff" id="context"> import org.asdt.core.internal.antlr.AS3Parser;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.ActionScriptFactory;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.SyntaxException;
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.DocComment;
+import uk.co.badgersinfoil.metaas.dom.DocTag;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenSource;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenStream;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTreeAdaptor;
+import uk.co.badgersinfoil.metaas.impl.parser.javadoc.JavadocLexer;
+import uk.co.badgersinfoil.metaas.impl.parser.javadoc.JavadocParser;
</pre><pre class="diff" id="context"> 
 
 /**
  * Helpers for dealing with documentation-comments.
  */
 class DocCommentUtils {
</pre><pre class="diff" id="added">+        private static final LinkedListTreeAdaptor TREE_ADAPTOR = new LinkedListTreeAdaptor();
+
</pre><pre class="diff" id="context">         private DocCommentUtils() { /* hide ctor */ }
 
         public static String getDocComment(LinkedListTree node) {
</pre><pre class="diff"><small id="info">@@ -85,21 +100,25 @@
</small></pre><pre class="diff" id="context">                 if (tok == null) {
                         LinkedListToken comment = TokenBuilder.newMLComment(text);
 
</pre><pre class="diff" id="removed">-                        LinkedListToken nl = TokenBuilder.newNewline();
-
-                        // TODO: try harder to find the right place/line to
-                        // insert the comment
-                        node.getStartToken().beforeInsert(comment);
-                        comment.beforeInsert(nl);
-                        if (indent.length() &gt; 0) {
-                                LinkedListToken indentTok = TokenBuilder.newWhiteSpace(indent);
-                                comment.beforeInsert(indentTok);
-                        }
</pre><pre class="diff" id="added">+                        insertDocComment(node, indent, comment);
</pre><pre class="diff" id="context">                 } else {
                         tok.setText(text);
                 }
         }
 
</pre><pre class="diff" id="added">+        private static void insertDocComment(LinkedListTree node, String indent, LinkedListToken comment) {
+                LinkedListToken nl = TokenBuilder.newNewline();
+
<a name="task3" />+                // <span class="task">TODO</span>: try harder to find the right place/line to
+                // insert the comment
+                node.getStartToken().beforeInsert(comment);
+                comment.beforeInsert(nl);
+                if (indent.length() &gt; 0) {
+                        LinkedListToken indentTok = TokenBuilder.newWhiteSpace(indent);
+                        comment.beforeInsert(indentTok);
+                }
+        }
+
</pre><pre class="diff" id="context">         private static void assertValidContent(String text) {
                 int pos = text.indexOf("*/");
                 if (pos != -1) {
</pre><pre class="diff"><small id="info">@@ -110,4 +129,182 @@
</small></pre><pre class="diff" id="context">         public static void increaseCommentIndent(LinkedListToken tok, String indent) {
                 tok.setText(tok.getText().replaceAll("(\n|\r\n|\r)", "$1"+indent));
         }
</pre><pre class="diff" id="added">+
+        public static String getDescriptionString(LinkedListTree ast) {
+                LinkedListTree javadoc = buildJavadoc(ast);
+                if (javadoc == null) {
+                        return null;
+                }
+                LinkedListTree desc = javadoc.getFirstChild();
+                return stringify(desc);
+        }
+
+        public static LinkedListTree buildJavadoc(LinkedListTree ast) {
+                LinkedListToken doc = findDocCommentToken(ast);
+                if (doc == null) {
+                        return null;
+                }
+                String body = getCommentBody(doc);
+                LinkedListTree javadoc = parse(body);
+                return javadoc;
+        }
+
+        private static String getCommentBody(LinkedListToken doc) {
+                String text = doc.getText();
+                return text.substring(3, text.length()-2);
+        }
+
+        private static String stringify(LinkedListTree ast) {
+                StringBuffer result = new StringBuffer();
+                for (LinkedListToken tok=ast.getStartToken(); tok!=null&amp;&amp;tok.getType()!=-1; tok=tok.getNext()) {
+                        result.append(stringify(tok));
+                        if (tok == ast.getStopToken()) {
+                                break;
+                        }
+                }
+                return result.toString();
+        }
+
+        private static String stringify(LinkedListToken tok) {
+                switch (tok.getType()) {
+                        case JavadocParser.NL:
<a name="task4" />+                                // <span class="task">TODO</span>: use the original line-ending format
+                                return "\n";
+                        default:
+                                return tok.getText();
+                }
+        }
+
+        public static void setDescriptionString(LinkedListTree ast, String description) {
+                LinkedListToken doc = findDocCommentToken(ast);
+                LinkedListTree javadoc = null;
+                LinkedListTree desc = null;
+                if (doc != null) {
+                        javadoc = parse(getCommentBody(doc));
+                        trimEOF(javadoc);
+                        desc = javadoc.getFirstChild();
+                }
+                if (description == null) {
+                        if (desc != null) {
+                                ASTUtils.deleteAllChildren(desc);
+                                doc.setText("/**"+ASTUtils.stringifyNode(javadoc)+"*/");
+                        }
+                        return;
+                }
+                String newline = getNewlineText(ast, javadoc);
+                if (!description.startsWith("\n")) {
+                        description = "\n" + description;
+                }
+                description = description.replaceAll("\n", newline);
+                LinkedListTree newDesc = parseDescription(description);
+                if (doc == null) {
+                        String indent = ASTUtils.findIndent(ast);
+                        doc = TokenBuilder.newMLComment("/**"+ASTUtils.stringifyNode(newDesc)+"\n"+indent+" */");
+                        insertDocComment(ast, indent, doc);
+                } else {
+                        newDesc.appendToken(new LinkedListToken(JavadocParser.NL, newline));
+                        javadoc.setChildWithTokens(0, newDesc);
+                        doc.setText("/**"+ASTUtils.stringifyNode(javadoc)+"*/");
+                }
+        }
+
+        public static String getNewlineText(LinkedListTree ast, LinkedListTree javadoc) {
+                String newline = null;
+                if (javadoc != null) {
+                        newline = findNewline(javadoc);
+                }
+                if (newline == null) {
<a name="task5" />+                        newline = "\n"+ASTUtils.findIndent(ast)+" * ";  // <span class="task">TODO</span>: use document existing end-of-line format
+                }
+                return newline;
+        }
+
+        private static String findNewline(LinkedListTree javadoc) {
+                LinkedListToken tok=javadoc.getStopToken();
+                if (tok.getType() == JavadocParser.NL) {
+                        // Skip the very-last NL, since this will preceed the
+                        // closing-comment marker, and therefor will lack the
+                        // '*' that should be present at the start of every
+                        // other line,
+                        tok=tok.getPrev();
+                }
+                for (; tok!=null; tok=tok.getPrev()) {
+                        if (tok.getType() == JavadocParser.NL) {
+                                return tok.getText();
+                        }
+                }
+                return null;
+        }
+
+        private static LinkedListTree parseDescription(String description) {
+                try {
+                        JavadocParser parser = parserOn(description);
+                        LinkedListTree desc = (LinkedListTree)parser.description().getTree();
+                        LinkedListToken after = (LinkedListToken)parser.getTokenStream().LT(1);
+                        if (!isEOF(after)) {
+                                throw new SyntaxException("trailing content after description: "+ActionScriptFactory.str(after.getText()));
+                        }
+                        trimEOF(desc);
+                        return desc;
+                } catch (IOException e) {
+                        throw new SyntaxException(e);
+                } catch (RecognitionException e) {
+                        throw new SyntaxException(e);
+                }
+        }
+
+        private static boolean isEOF(LinkedListToken after) {
+                return after.getType() == JavadocParser.EOF;
+        }
+
+        /**
+         * removes trailing enf-of-file tokens from the AST
+         */
+        private static void trimEOF(LinkedListTree desc) {
+                LinkedListTree lastChild = desc.getLastChild();
+                if (lastChild != null) {
+                        trimEOF(lastChild);
+                }
+                while (isEOF(desc.getStopToken())) {
+                        desc.setStopToken(desc.getStopToken().getPrev());
+                }
+        }
+
+        private static LinkedListTree parse(String body) {
+                try {
+                        JavadocParser parser = parserOn(body);
+                        return (LinkedListTree)parser.comment_body().getTree();
+                } catch (IOException e) {
+                        throw new SyntaxException(e);
+                } catch (RecognitionException e) {
+                        throw new SyntaxException(e);
+                }
+        }
+
+        private static JavadocParser parserOn(String text) throws IOException {
+                StringReader in = new StringReader(text);
+                ANTLRReaderStream cs = new ANTLRReaderStream(in);
+                JavadocLexer lexer = new JavadocLexer(cs);
+                LinkedListTokenSource source = new LinkedListTokenSource(lexer);
+                LinkedListTokenStream stream = new LinkedListTokenStream(source);
+                JavadocParser parser = new JavadocParser(stream);
+                parser.setTreeAdaptor(TREE_ADAPTOR);
+                return parser;
+        }
+
+        public static ASTDocComment createDocComment(LinkedListTree ast) {
+                return new ASTDocComment(ast);
+        }
+
+        public static DocTag findParam(DocComment doc, String name) {
+                Iterator params = doc.findTags("param");
+                Pattern p = Pattern.compile("\\s*\\Q"+name+"\\E\\b");
+                while (params.hasNext()) {
+                        DocTag param = (DocTag)params.next();
+                        if (p.matcher(param.getBodyString()).lookingAt()) {
+                                return param;
+                        }
+                }
+                return null;
+        }
</pre><pre class="diff" id="context"> }
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file15" /><div class="file">
<span class="pathname">metaas/trunk/src/test/java/uk/co/badgersinfoil/metaas</span><br />
<div class="fileheader"><big><b>DocCommentTests.java</b></big> <small id="info">428 -&gt; 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/test/java/uk/co/badgersinfoil/metaas/DocCommentTests.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/test/java/uk/co/badgersinfoil/metaas/DocCommentTests.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -1,11 +1,15 @@
</small></pre><pre class="diff" id="context"> package uk.co.badgersinfoil.metaas;
 
 import java.io.IOException;
</pre><pre class="diff" id="removed">-
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.ASArg;
</pre><pre class="diff" id="context"> import uk.co.badgersinfoil.metaas.dom.ASClassType;
 import uk.co.badgersinfoil.metaas.dom.ASCompilationUnit;
</pre><pre class="diff" id="added">+import uk.co.badgersinfoil.metaas.dom.DocComment;
+import uk.co.badgersinfoil.metaas.dom.ASMethod;
+import uk.co.badgersinfoil.metaas.dom.Visibility;
</pre><pre class="diff" id="context"> import junit.framework.TestCase;
 
</pre><pre class="diff" id="added">+
</pre><pre class="diff" id="context"> public class DocCommentTests extends TestCase {
 
         private ActionScriptFactory fact = new ActionScriptFactory();
</pre><pre class="diff"><small id="info">@@ -24,10 +28,58 @@
</small></pre><pre class="diff" id="context"> 
         public void testEndOfCommentMarker() {
                 try {
</pre><pre class="diff" id="removed">-                        clazz.setDocComment("*/");
</pre><pre class="diff" id="added">+                        clazz.getDocumentation().setDocComment("*/");
</pre><pre class="diff" id="context">                         fail("should not allow '*/' within a doc-comment");
                 } catch (SyntaxException e) {
                         // expected
                 }
         }
</pre><pre class="diff" id="removed">-}
</pre><pre class="diff" id="added">+
+        public void testSetNewDescription() {
+                clazz.setDescription("hello");
+                assertEquals("hello", clazz.getDescriptionString().trim());
+        }
+
+        public void testSetBadDescription() {
+                try {
+                        clazz.setDescription("hello\n@param foo great");
+                        fail("should have rejected description with trailing tagged-paragraph");
+                } catch (SyntaxException e) {
+                        // expected
+                }
+        }
+
+        public void testGetDescriptionNoDocs() {
+                assertNull(clazz.getDescriptionString());
+        }
+
+        public void testRemoveDescription() {
+                clazz.setDescription(null);
+                assertEquals(null, clazz.getDescriptionString());
+        }
+
+        public void testGetExistingDescription() {
+                clazz.getDocumentation().setDocComment("hello world\n@param foo bar");
+                assertEquals("hello world", clazz.getDescriptionString().trim());
+        }
+
+        public void testNewArgNoDocs() {
+                ASMethod meth = clazz.newMethod("test", Visibility.PUBLIC, "void");
+                ASArg test = meth.addParam("test", "String");
+                assertNull(test.getDescriptionString());
+                test.setDescription("a test!");
+                assertEquals("a test!", test.getDescriptionString().trim());
+                // insert a description before the @param
+                meth.setDescription("foo\nbar");
+                assertEquals("foo\nbar", meth.getDescriptionString().trim());
+                String actualDesc = test.getDescriptionString();
+                assertNotNull(actualDesc);
+                assertEquals("a test!", actualDesc.trim());
+        }
+        
+        public void testDocumentation() {
+                DocComment doc = clazz.getDocumentation();
+                assertNotNull(doc);
+                assertNull(doc.getDescriptionString());
+        }
+}
</pre><pre class="diff"><small id="info">\ No newline at end of file
</small></pre></div>
<hr /><a name="file16" /><div class="file">
<span class="pathname" id="added">metaas/trunk/src/test/java/uk/co/badgersinfoil/metaas/impl/parser/javadoc</span><br />
<div class="fileheader" id="added"><big><b>JavadocParserTests.java</b></big> <small id="info">added at 429</small></div>
<pre class="diff"><small id="info">--- trunk/src/test/java/uk/co/badgersinfoil/metaas/impl/parser/javadoc/JavadocParserTests.java        2007-02-22 23:14:46 UTC (rev 428)
+++ trunk/src/test/java/uk/co/badgersinfoil/metaas/impl/parser/javadoc/JavadocParserTests.java        2007-02-22 23:25:32 UTC (rev 429)
@@ -0,0 +1,75 @@
</small></pre><pre class="diff" id="added">+package uk.co.badgersinfoil.metaas.impl.parser.javadoc;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringReader;
+import org.antlr.runtime.ANTLRReaderStream;
+import org.antlr.runtime.RecognitionException;
+import uk.co.badgersinfoil.metaas.impl.antlr.ASTDot;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenSource;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTokenStream;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
+import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTreeAdaptor;
+import junit.framework.TestCase;
+
+public class JavadocParserTests extends TestCase {
+        private static final LinkedListTreeAdaptor TREE_ADAPTOR = new LinkedListTreeAdaptor();
+
+        public void testEmptyBody() throws IOException, RecognitionException {
+                LinkedListTree tree = parse("");
+                assertEquals(JavadocParser.JAVADOC, tree.getType());
+                assertEquals(JavadocParser.DESCRIPTION, tree.getFirstChild().getType());
+        }
+
+        public void testParaBasic() throws IOException, RecognitionException {
+                String doc = "* desc\n" +
+                             "* ription\n" +
+                             "* @param foo bar";
+                LinkedListTree tree = parse(doc);
+
+                LinkedListTree desc = (LinkedListTree)tree.getChild(0);
+                assertEquals(JavadocParser.DESCRIPTION, desc.getType());
+
+                LinkedListTree param = (LinkedListTree)tree.getChild(1);
+                assertEquals(JavadocParser.PARA_TAG, param.getType());
+                assertEquals("@param", param.getFirstChild().getText());
+        }
+
+        public void testLonelyParaTag() throws IOException, RecognitionException {
+                String doc = "\n\t\t * @param test a test!\n\t\t ";
+                LinkedListTree tree = parse(doc);
+        }
+
+        public void testJustNewlines() throws IOException, RecognitionException {
+                String doc = "\n\n";
+                LinkedListTree tree = parse(doc);
+        }
+
+        public void testInlineTag() throws IOException, RecognitionException {
+                LinkedListTree tree = parse("{@link foo}");
+//OutputStreamWriter out = new OutputStreamWriter(System.out);
+//new ASTDot(out).dotify(tree);
+//out.flush();
+                LinkedListTree desc = tree.getFirstChild();
+                LinkedListTree tag = desc.getFirstChild();
+                assertEquals(JavadocParser.INLINE_TAG, tag.getType());
+                assertEquals("@link", tag.getFirstChild().getText());
+        }
+
+        private static LinkedListTree parse(String str) throws IOException, RecognitionException {
+                JavadocParser parser = parserOn(str);
+                return parser.comment_body().tree;
+        }
+
+        private static JavadocParser parserOn(String str) throws IOException {
+                StringReader in = new StringReader(str);
+                ANTLRReaderStream cs = new ANTLRReaderStream(in);
+                JavadocLexer lexer = new JavadocLexer(cs);
+                LinkedListTokenSource source = new LinkedListTokenSource(lexer);
+                LinkedListTokenStream stream = new LinkedListTokenStream(source);
+                JavadocParser parser = new JavadocParser(stream);
+                parser.setTreeAdaptor(TREE_ADAPTOR);
+//                parser.setInput(lexer, cs);
+                return parser;
+        }
+}
</pre></div>
<center><small><a href="http://www.badgers-in-foil.co.uk/projects/cvsspam/" title="commit -&gt; email">CVSspam</a> 0.2.12</small></center>
</body></html>