[armedbear-cvs] r13790 - trunk/abcl/src/org/armedbear/lisp
astalla at common-lisp.net
astalla at common-lisp.net
Tue Jan 17 20:26:21 UTC 2012
Author: astalla
Date: Tue Jan 17 12:26:21 2012
New Revision: 13790
Log:
[runtime-class] added auto getter/setter generation for fields.
Modified:
trunk/abcl/src/org/armedbear/lisp/runtime-class.lisp
Modified: trunk/abcl/src/org/armedbear/lisp/runtime-class.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/runtime-class.lisp Tue Jan 17 12:15:57 2012 (r13789)
+++ trunk/abcl/src/org/armedbear/lisp/runtime-class.lisp Tue Jan 17 12:26:21 2012 (r13790)
@@ -61,14 +61,7 @@
(class-add-attribute class-file (make-runtime-visible-annotations-attribute
:list (mapcar #'parse-annotation annotations))))
(setf method-implementation-fields (java::runtime-class-add-methods class-file methods))
- (dolist (field-spec fields)
- (destructuring-bind (name type &key (modifiers '(:public)) annotations) field-spec
- (let ((field (make-field name (if (keywordp type) type (make-jvm-class-name type))
- :flags modifiers)))
- (when annotations
- (field-add-attribute field (make-runtime-visible-annotations-attribute
- :list (mapcar #'parse-annotation annotations))))
- (class-add-field class-file field))))
+ (java::runtime-class-add-fields class-file fields)
(if (null constructors)
(let ((ctor (make-jvm-method :constructor :void nil :flags '(:public))))
(class-add-method class-file ctor)
@@ -85,6 +78,11 @@
(write-sequence (java::list-from-jarray (sys::%get-output-stream-bytes stream)) f))
(values class-file method-implementation-fields)))
+(defun java::make-accessor-name (prefix name)
+ (let ((initial (char-upcase (aref name 0)))
+ (rest (subseq name 1)))
+ (format nil "~A~A~A" prefix initial rest)))
+
(defun java::runtime-class-add-methods (class-file methods)
(let (method-implementation-fields)
(dolist (m methods)
@@ -153,6 +151,46 @@
(error "Unsupported return type: ~A" return-type)))))))
method-implementation-fields))
+(defun java::runtime-class-add-fields (class-file fields)
+ (dolist (field-spec fields)
+ (destructuring-bind (name type &key (modifiers '(:public)) annotations
+ (getter nil getter-p) (setter nil setter-p)
+ (property (and (not getter-p) (not setter-p))))
+ field-spec
+ (let* ((type (if (keywordp type) type (make-jvm-class-name type)))
+ (field (make-field name type :flags modifiers)))
+ (when (member :static modifiers)
+ (setf property nil getter nil setter nil))
+ (when annotations
+ (field-add-attribute field (make-runtime-visible-annotations-attribute
+ :list (mapcar #'parse-annotation annotations))))
+ (class-add-field class-file field)
+ (when (or getter property)
+ (unless (stringp getter)
+ (setf getter (java::make-accessor-name "get" (if (stringp property) property name))))
+ (let ((jmethod (make-jvm-method getter type nil :flags '(:public))))
+ (class-add-method class-file jmethod)
+ (with-code-to-method (class-file jmethod)
+ (aload 0)
+ (emit-getfield (class-file-class class-file) name type)
+ (cond
+ ((jvm-class-name-p type) (emit 'areturn))
+ ((eq type :int) (emit 'ireturn))
+ (t (error "Unsupported getter return type: ~A" type))))))
+ (when (or setter property)
+ (unless (stringp setter)
+ (setf setter (java::make-accessor-name "set" (if (stringp property) property name))))
+ (let ((jmethod (make-jvm-method setter :void (list type) :flags '(:public))))
+ (class-add-method class-file jmethod)
+ (with-code-to-method (class-file jmethod)
+ (aload 0)
+ (cond
+ ((jvm-class-name-p type) (aload 1))
+ ((eq type :int) (iload 1))
+ (t (error "Unsupported setter parameter type: ~A" type)))
+ (emit-putfield (class-file-class class-file) name type)
+ (emit 'return))))))))
+
(defmacro java:define-java-class () :todo)
(defun parse-annotation (annotation)
@@ -180,16 +218,16 @@
(t (make-primitive-or-string-annotation-element :name name :value value)))))))
;;TODO:
-;; - Fields: test
-;; - Properties + optional accessors (CLOS methods)
;; - Function calls with 8+ args
-;; - super?
-;; - Constructors?
+;; - super method invocation. Idea: generate companion methods super_... to use with plain jcall. Add a flag per method to optionally disable this when not needed.
+;; - Constructors
+;; - optional accessors (CLOS methods) for properties?
#+example
(java:jnew-runtime-class
"Foo"
:interfaces (list "java.lang.Comparable")
+ :fields (list '("someField" "java.lang.String") '("anotherField" "java.lang.Object" :getter t))
:methods (list
(list "foo" :void '("java.lang.Object")
(lambda (this that) (print (list this that)))
More information about the armedbear-cvs
mailing list