Changeset 13790


Ignore:
Timestamp:
01/17/12 20:26:21 (9 years ago)
Author:
astalla
Message:

[runtime-class] added auto getter/setter generation for fields.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/runtime-class.lisp

    r13785 r13790  
    6262                                       :list (mapcar #'parse-annotation annotations))))
    6363    (setf method-implementation-fields (java::runtime-class-add-methods class-file methods))
    64     (dolist (field-spec fields)
    65       (destructuring-bind (name type &key (modifiers '(:public)) annotations) field-spec
    66         (let ((field (make-field name (if (keywordp type) type (make-jvm-class-name type))
    67                                  :flags modifiers)))
    68           (when annotations
    69             (field-add-attribute field (make-runtime-visible-annotations-attribute
    70                                         :list (mapcar #'parse-annotation annotations))))
    71           (class-add-field class-file field))))
     64    (java::runtime-class-add-fields class-file fields)
    7265    (if (null constructors)
    7366      (let ((ctor (make-jvm-method :constructor :void nil :flags '(:public))))
     
    8578      (write-sequence (java::list-from-jarray (sys::%get-output-stream-bytes stream)) f))
    8679    (values class-file method-implementation-fields)))
     80
     81(defun java::make-accessor-name (prefix name)
     82  (let ((initial (char-upcase (aref name 0)))
     83        (rest (subseq name 1)))
     84    (format nil "~A~A~A" prefix initial rest)))
    8785
    8886(defun java::runtime-class-add-methods (class-file methods)
     
    154152    method-implementation-fields))
    155153
     154(defun java::runtime-class-add-fields (class-file fields)
     155  (dolist (field-spec fields)
     156    (destructuring-bind (name type &key (modifiers '(:public)) annotations
     157                              (getter nil getter-p) (setter nil setter-p)
     158                              (property (and (not getter-p) (not setter-p))))
     159        field-spec
     160      (let* ((type (if (keywordp type) type (make-jvm-class-name type)))
     161             (field (make-field name type :flags modifiers)))
     162        (when (member :static modifiers)
     163          (setf property nil getter nil setter nil))
     164        (when annotations
     165          (field-add-attribute field (make-runtime-visible-annotations-attribute
     166                                      :list (mapcar #'parse-annotation annotations))))
     167        (class-add-field class-file field)
     168        (when (or getter property)
     169          (unless (stringp getter)
     170            (setf getter (java::make-accessor-name "get" (if (stringp property) property name))))
     171          (let ((jmethod (make-jvm-method getter type nil :flags '(:public))))
     172            (class-add-method class-file jmethod)
     173            (with-code-to-method (class-file jmethod)
     174              (aload 0)
     175              (emit-getfield (class-file-class class-file) name type)
     176              (cond
     177                ((jvm-class-name-p type) (emit 'areturn))
     178                ((eq type :int) (emit 'ireturn))
     179                (t (error "Unsupported getter return type: ~A" type))))))
     180        (when (or setter property)
     181          (unless (stringp setter)
     182            (setf setter (java::make-accessor-name "set" (if (stringp property) property name))))
     183          (let ((jmethod (make-jvm-method setter :void (list type) :flags '(:public))))
     184            (class-add-method class-file jmethod)
     185            (with-code-to-method (class-file jmethod)
     186              (aload 0)
     187              (cond
     188                ((jvm-class-name-p type) (aload 1))
     189                ((eq type :int) (iload 1))
     190                (t (error "Unsupported setter parameter type: ~A" type)))
     191              (emit-putfield (class-file-class class-file) name type)
     192              (emit 'return))))))))
     193
    156194(defmacro java:define-java-class () :todo)
    157195
     
    181219
    182220;;TODO:
    183 ;; - Fields: test
    184 ;; - Properties + optional accessors (CLOS methods)
    185221;; - Function calls with 8+ args
    186 ;; - super?
    187 ;; - Constructors?
     222;; - 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.
     223;; - Constructors
     224;; - optional accessors (CLOS methods) for properties?
    188225
    189226#+example
     
    191228 "Foo"
    192229 :interfaces (list "java.lang.Comparable")
     230 :fields (list '("someField" "java.lang.String") '("anotherField" "java.lang.Object" :getter t))
    193231 :methods (list
    194232           (list "foo" :void '("java.lang.Object")
Note: See TracChangeset for help on using the changeset viewer.