Hi folks,
Here's the first go at the DocString annotation.
Changes:
Added org/armedbear/lisp/DocString.java, defining the @DocString annotation.
Modified Function.java. Now it will check to see if there is an annotation, and set its data from there (overriding the arglist and docstring constructor arguments if provided). Also removed some (but not all) existing code duplication in the constructors.
Added a constructor to Primitive, Primitive(Symbol), since it wasn't there, and becomes relevant when moving documentation out of a constructor and into a @DocString annotation.
Added/replaced a bit of documentation in Java.java using the new annotation syntax, to give a flavour of what it does. (More actual documentation patches in progress).
Conformance with ansi.interpreted and ansi.compiled has not been affected, but confirmation would be prudent since this is new to me.
Regards, Matt
# 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,23 @@ */ private final LispObject loadedFrom;
+ /** + * Examine this object's class to determine if there is a DocString annotation, and if so, + * add the documentation. + */ + private void installDocString() { + DocString ds = getClass().getAnnotation(DocString.class); + if(ds != null) { + LispObject name = getLambdaName(); + String arglist = ds.args(); + String docstring = ds.doc(); + if(arglist.length() != 0) + setLambdaList(new SimpleString(arglist)); + if(name instanceof Symbol && docstring.length() != 0) + ((Symbol)name).setDocumentation(Symbol.FUNCTION, new SimpleString(docstring)); + } + } + protected Function() { LispObject loadTruename = Symbol.LOAD_TRUENAME.symbolValueNoThrow(); loadedFrom = loadTruename != null ? loadTruename : NIL; @@ -53,23 +70,31 @@
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) symbol.setBuiltInFunction(true); setLambdaName(symbol); + installDocString(); } }
+ 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 +104,14 @@ 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)); + installDocString(); } - }
- public Function(String name, String arglist) - { - this(name); - setLambdaList(new SimpleString(arglist)); - } - public Function(String name, Package pkg) { this(name, pkg, false); @@ -127,6 +147,7 @@ if (docstring != null) symbol.setDocumentation(Symbol.FUNCTION, new SimpleString(docstring)); + installDocString(); } }
Index: org/armedbear/lisp/Java.java --- org/armedbear/lisp/Java.java Base (BASE) +++ org/armedbear/lisp/Java.java Locally Modified (Based On LOCAL) @@ -60,6 +60,7 @@ }
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() @@ -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 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 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/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);
armedbear-devel@common-lisp.net