# doc-string.diff
Index: org/armedbear/lisp/DocString.java
--- org/armedbear/lisp/DocString.java Locally New
+++ org/armedbear/lisp/DocString.java Locally New
@@ -0,0 +1,44 @@
+/*
+ * DocString.java
+ *
+ * Copyright (C) 2010 Matt Seddon
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent
+ * modules, and to copy and distribute the resulting executable under
+ * terms of your choice, provided that you also meet, for each linked
+ * independent module, the terms and conditions of the license of that
+ * module.  An independent module is a module which is not derived from
+ * or based on this library.  If you modify this library, you may extend
+ * this exception to your version of the library, but you are not
+ * obligated to do so.  If you do not wish to do so, delete this
+ * exception statement from your version.
+ */
+package org.armedbear.lisp;
+
+import java.lang.annotation.*;
+
+/**
+ * An annotation type to expose documentation to ABCL.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DocString {
+    public String name() default "";
+    public String doc() default "";
+    public String args() default "";
+}
Index: org/armedbear/lisp/Function.java
--- org/armedbear/lisp/Function.java Base (BASE)
+++ org/armedbear/lisp/Function.java Locally Modified (Based On LOCAL)
@@ -46,6 +46,11 @@
      */
     private final LispObject loadedFrom;
 
+    /**
+     * Examine this object's class to determine if there is a DocString annotation, and if so,
+     * add the documentation.
+     */
+
     protected Function() {
 	LispObject loadTruename = Symbol.LOAD_TRUENAME.symbolValueNoThrow();
 	loadedFrom = loadTruename != null ? loadTruename : NIL;
@@ -53,7 +58,14 @@
 
     public Function(String name)
     {
+        this(name, (String)null);
+    }
+
+    public Function(String name, String arglist)
+    {
 	this();
+        if(arglist != null)
+            setLambdaList(new SimpleString(arglist));
         if (name != null) {
             Symbol symbol = Symbol.addFunction(name.toUpperCase(), this);
             if (cold)
@@ -62,14 +74,14 @@
         }
     }
 
+    public Function(Symbol symbol)
+    {
+	this(symbol, null, null);
+    }
+
     public Function(Symbol symbol, String arglist)
     {
-	this();
-        symbol.setSymbolFunction(this);
-        if (cold)
-            symbol.setBuiltInFunction(true);
-        setLambdaName(symbol);
-        setLambdaList(new SimpleString(arglist));
+	this(symbol, arglist, null);
     }
 
     public Function(Symbol symbol, String arglist, String docstring)
@@ -79,19 +91,13 @@
         if (cold)
             symbol.setBuiltInFunction(true);
         setLambdaName(symbol);
+        if(arglist != null)
         setLambdaList(new SimpleString(arglist));
-        if (docstring != null) {
+        if (docstring != null)
             symbol.setDocumentation(Symbol.FUNCTION,
                                     new SimpleString(docstring));
         }
-    }
 
-    public Function(String name, String arglist)
-    {
-        this(name);
-        setLambdaList(new SimpleString(arglist));
-    }
-
     public Function(String name, Package pkg)
     {
         this(name, pkg, false);
Index: org/armedbear/lisp/Java.java
--- org/armedbear/lisp/Java.java Base (BASE)
+++ org/armedbear/lisp/Java.java Locally Modified (Based On LOCAL)
@@ -60,11 +60,12 @@
     }
 
     private static final Primitive ENSURE_JAVA_OBJECT = new pf_ensure_java_object();
+    @DocString(args="obj", doc="Ensures OBJ is wrapped in a JAVA-OBJECT, wrapping it if necessary.")
     private static final class pf_ensure_java_object extends Primitive 
     {
         pf_ensure_java_object() 
         {
-            super("ensure-java-object", PACKAGE_JAVA, true, "obj");
+            super("ensure-java-object", PACKAGE_JAVA, true);
         }
 
         @Override
@@ -131,13 +132,13 @@
 
     // ### jclass name-or-class-ref &optional class-loader => class-ref
     private static final Primitive JCLASS = new pf_jclass();
+    @DocString(args="name-or-class-ref &optional class-loader", doc="Returns a reference to the Java class designated by NAME-OR-CLASS-REF. If the CLASS-LOADER parameter is passed, the class is resolved with respect to the given ClassLoader.")
     private static final class pf_jclass extends Primitive 
     {
 
         pf_jclass() 
         {
-            super(Symbol.JCLASS, "name-or-class-ref &optional class-loader",
-                  "Returns a reference to the Java class designated by NAME-OR-CLASS-REF. If the CLASS-LOADER parameter is passed, the class is resolved with respect to the given ClassLoader.");
+            super(Symbol.JCLASS);
         }
 
         @Override
@@ -294,12 +295,12 @@
 
     // ### jconstructor class-ref &rest parameter-class-refs
     private static final Primitive JCONSTRUCTOR = new pf_jconstructor();
+    @DocString(args="class-ref &rest parameter-class-refs", doc="Returns a reference to the Java constructor of CLASS-REF with the given PARAMETER-CLASS-REFS.")
     private static final class pf_jconstructor extends Primitive
     {
         pf_jconstructor() 
         {
-            super("jconstructor", PACKAGE_JAVA, true,
-                  "class-ref &rest parameter-class-refs");
+            super("jconstructor", PACKAGE_JAVA, true);
         }
 
         @Override
@@ -344,12 +345,13 @@
 
     // ### jmethod class-ref name &rest parameter-class-refs
     private static final Primitive JMETHOD = new pf_jmethod();
+
+    @DocString(args="class-ref name &rest parameter-class-refs", doc="Returns a reference to the Java method NAME of CLASS-REF with the given PARAMETER-CLASS-REFS.")
     private static final class pf_jmethod extends Primitive 
     {
         pf_jmethod() 
         {
-            super("jmethod", PACKAGE_JAVA, true,
-                  "class-ref name &rest parameter-class-refs");
+            super("jmethod", PACKAGE_JAVA, true);
         }
 
         @Override
Index: org/armedbear/lisp/LispObject.java
--- org/armedbear/lisp/LispObject.java Base (BASE)
+++ org/armedbear/lisp/LispObject.java Locally Modified (Based On LOCAL)
@@ -657,6 +657,23 @@
         if (entry instanceof Cons)
           return ((Cons)entry).cdr;
       }
+    if(docType == Symbol.FUNCTION && this instanceof Symbol) {
+        Object fn = ((Symbol)this).getSymbolFunction();
+        if(fn instanceof Function) {
+            DocString ds = fn.getClass().getAnnotation(DocString.class);
+            if(ds != null) {
+                String arglist = ds.args();
+                String docstring = ds.doc();
+                if(arglist.length() != 0)
+                    ((Function)fn).setLambdaList(new SimpleString(arglist));
+                if(docstring.length() != 0) {
+                    SimpleString doc = new SimpleString(docstring);
+                    ((Symbol)this).setDocumentation(Symbol.FUNCTION, doc);
+                    return doc;
+                }
+            }
+        }
+    }
     return NIL;
   }
 
Index: org/armedbear/lisp/Primitive.java
--- org/armedbear/lisp/Primitive.java Base (BASE)
+++ org/armedbear/lisp/Primitive.java Locally Modified (Based On LOCAL)
@@ -45,6 +45,11 @@
         super(name);
     }
 
+    public Primitive(Symbol symbol)
+    {
+        super(symbol);
+    }
+
     public Primitive(Symbol symbol, String arglist)
     {
         super(symbol, arglist);
