[armedbear-cvs] r12660 - trunk/abcl/src/org/armedbear/lisp
Alessio Stalla
astalla at common-lisp.net
Sat May 8 21:55:48 UTC 2010
Author: astalla
Date: Sat May 8 17:55:47 2010
New Revision: 12660
Log:
Fixed and rationalized class precedence list computation for java-class metaclasses.
Modified:
trunk/abcl/src/org/armedbear/lisp/java.lisp
Modified: trunk/abcl/src/org/armedbear/lisp/java.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/java.lisp (original)
+++ trunk/abcl/src/org/armedbear/lisp/java.lisp Sat May 8 17:55:47 2010
@@ -325,26 +325,65 @@
(java:java-exception-cause e)))))
;;; JAVA-CLASS support
+(defconstant +java-lang-object+ (jclass "java.lang.Object"))
(defclass java-class (standard-class)
((jclass :initarg :java-class
:initform (error "class is required")
:reader java-class-jclass)))
+;;init java.lang.Object class
+(defconstant +java-lang-object-class+
+ (%register-java-class +java-lang-object+
+ (mop::ensure-class (make-symbol "java.lang.Object")
+ :metaclass (find-class 'java-class)
+ :direct-superclasses (list (find-class 'java-object))
+ :java-class +java-lang-object+)))
+
(defun ensure-java-class (jclass)
(let ((class (%find-java-class jclass)))
(if class
class
(%register-java-class
- jclass (mop::ensure-class (make-symbol (jclass-name jclass))
- :metaclass (find-class 'java-class)
- :direct-superclasses (if (jclass-superclass-p jclass (jclass "java.lang.Object"))
- (list (find-class 'java-object))
- (mapcar #'ensure-java-class
- (delete nil
- (concatenate 'list (list (jclass-superclass jclass))
- (jclass-interfaces jclass)))))
- :java-class jclass)))))
+ jclass (mop::ensure-class
+ (make-symbol (jclass-name jclass))
+ :metaclass (find-class 'java-class)
+ :direct-superclasses (mapcar #'ensure-java-class
+ (remove-duplicates
+ (delete nil
+ (concatenate 'list
+ (list (jclass-superclass jclass))
+ (jclass-interfaces jclass)))
+ :key #'jclass-name :test #'string=))
+ :java-class jclass)))))
+
+(defmethod mop::compute-class-precedence-list ((class java-class))
+ "Sort classes this way:
+ 1. Java classes (but not java.lang.Object)
+ 2. Java interfaces
+ 3. java.lang.Object
+ 4. other classes
+ Rationale:
+ 1. Concrete classes are the most specific.
+ 2. Then come interfaces.
+ So if a generic function is specialized both on an interface and a concrete class,
+ the concrete class comes first.
+ 3. because everything is an Object.
+ 4. to handle base CLOS classes.
+ Note: Java interfaces are not sorted among themselves in any way, so if a
+ gf is specialized on two different interfaces and you apply it to an object that
+ implements both, it is unspecified which method will be called."
+ (let ((cpl (call-next-method)))
+ (flet ((score (class)
+ (if (not (typep class 'java-class))
+ 4
+ (cond
+ ((jcall (jmethod "java.lang.Object" "equals" "java.lang.Object")
+ (java-class-jclass class) +java-lang-object+) 3)
+ ((jclass-interface-p (java-class-jclass class)) 2)
+ (t 1)))))
+ (stable-sort cpl #'(lambda (x y)
+ (< (score x) (score y)))))))
(defmethod make-instance ((class java-class) &rest initargs &key &allow-other-keys)
(declare (ignore initargs))
More information about the armedbear-cvs
mailing list