1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
10 (defpackage :sb-introspect-test
11 (:use
"SB-INTROSPECT" "CL" "SB-RT"))
13 (in-package :sb-introspect-test
)
15 (deftest function-lambda-list
.1
16 (function-lambda-list 'cl-user
::one
)
17 (cl-user::a cl-user
::b cl-user
::c
))
19 (deftest function-lambda-list
.2
20 (function-lambda-list 'the
)
21 (sb-c::value-type sb-c
::form
))
23 (deftest function-lambda-list
.3
24 (function-lambda-list #'(sb-pcl::slow-method cl-user
::j
(t)))
25 (sb-pcl::method-args sb-pcl
::next-methods
))
27 (deftest definition-source-plist
.1
28 (let* ((source (find-definition-source #'cl-user
::one
))
29 (plist (definition-source-plist source
)))
30 (values (= (definition-source-file-write-date source
)
31 (file-write-date "test.lisp"))
32 (or (equal (getf plist
:test-outer
)
37 (deftest definition-source-plist
.2
38 (let ((plist (definition-source-plist
39 (find-definition-source #'cl-user
::four
))))
40 (values (or (equal (getf plist
:test-outer
) "OUT")
42 (or (equal (getf plist
:test-inner
) "IN")
46 (defun matchp (object form-number
)
47 (let ((ds (sb-introspect:find-definition-source object
)))
48 (and (pathnamep (sb-introspect:definition-source-pathname ds
))
50 (first (sb-introspect:definition-source-form-path ds
))))))
52 (defun matchp-name (type object form-number
)
53 (let ((ds (car (sb-introspect:find-definition-sources-by-name object type
))))
54 (and (pathnamep (sb-introspect:definition-source-pathname ds
))
56 (first (sb-introspect:definition-source-form-path ds
))))))
58 (defun matchp-length (type object form-numbers
)
59 (let ((ds (sb-introspect:find-definition-sources-by-name object type
)))
60 (= (length ds
) form-numbers
)))
62 (deftest find-source-stuff
.1
63 (matchp-name :function
'cl-user
::one
2)
66 (deftest find-source-stuff
.2
67 (matchp #'cl-user
::one
2)
70 (deftest find-source-stuff
.3
71 (matchp-name :generic-function
'cl-user
::two
3)
74 (deftest find-source-stuff
.4
75 (matchp (car (sb-pcl:generic-function-methods
#'cl-user
::two
)) 4)
78 (deftest find-source-stuff
.5
79 (matchp-name :variable
'cl-user
::*a
* 8)
82 (deftest find-source-stuff
.6
83 (matchp-name :variable
'cl-user
::*b
* 9)
86 (deftest find-source-stuff
.7
87 (matchp-name :class
'cl-user
::a
10)
90 (deftest find-source-stuff
.8
91 (matchp-name :condition
'cl-user
::b
11)
94 (deftest find-source-stuff
.9
95 (matchp-name :structure
'cl-user
::c
12)
98 (deftest find-source-stuff
.10
99 (matchp-name :function
'cl-user
::make-c
12)
102 (deftest find-source-stuff
.11
103 (matchp-name :function
'cl-user
::c-e
12)
106 (deftest find-source-stuff
.12
107 (matchp-name :structure
'cl-user
::d
13)
110 (deftest find-source-stuff
.13
111 (matchp-name :function
'cl-user
::make-d
13)
114 (deftest find-source-stuff
.14
115 (matchp-name :function
'cl-user
::d-e
13)
118 (deftest find-source-stuff
.15
119 (matchp-name :package
'cl-user
::e
14)
122 (deftest find-source-stuff
.16
123 (matchp-name :symbol-macro
'cl-user
::f
15)
126 (deftest find-source-stuff
.17
127 (matchp-name :type
'cl-user
::g
16)
130 (deftest find-source-stuff
.18
131 (matchp-name :constant
'cl-user
::+h
+ 17)
134 (deftest find-source-stuff
.19
135 (matchp-length :method
'cl-user
::j
2)
138 (deftest find-source-stuff
.20
139 (matchp-name :macro
'cl-user
::l
20)
142 (deftest find-source-stuff
.21
143 (matchp-name :compiler-macro
'cl-user
::m
21)
146 (deftest find-source-stuff
.22
147 (matchp-name :setf-expander
'cl-user
::n
22)
150 (deftest find-source-stuff
.23
151 (matchp-name :function
'(setf cl-user
::o
) 23)
154 (deftest find-source-stuff
.24
155 (matchp-name :method
'(setf cl-user
::p
) 24)
158 (deftest find-source-stuff
.25
159 (matchp-name :macro
'cl-user
::q
25)
163 (deftest find-source-stuff
.26
164 (matchp-name :method-combination
'cl-user
::r
26)
168 (deftest find-source-stuff
.27
169 (matchp-name :setf-expander
'cl-user
::s
27)
172 (deftest find-source-stuff
.28
173 (let ((fin (make-instance 'sb-mop
:funcallable-standard-object
)))
174 (sb-mop:set-funcallable-instance-function fin
#'cl-user
::one
)
178 (deftest find-source-stuff
.29
181 (sb-profile:profile cl-user
::one
)
182 (matchp-name :function
'cl-user
::one
2))
183 (sb-profile:unprofile cl-user
::one
))
186 (deftest find-source-stuff
.30
187 ;; Test finding a type that isn't one
188 (not (find-definition-sources-by-name 'fboundp
:type
))
191 ;;; Check wrt. interplay of generic functions and their methods.
193 (defgeneric xuuq
(gf.a gf.b
&rest gf.rest
&key gf.k-X
))
194 (defmethod xuuq ((m1.a number
) m1.b
&rest m1.rest
&key gf.k-X m1.k-Y m1.k-Z
)
195 (declare (ignore m1.a m1.b m1.rest gf.k-X m1.k-Y m1.k-Z
))
197 (defmethod xuuq ((m2.a string
) m2.b
&rest m2.rest
&key gf.k-X m1.k-Y m2.k-Q
)
198 (declare (ignore m2.a m2.b m2.rest gf.k-X m1.k-Y m2.k-Q
))
201 ;; XUUQ's lambda list should look similiar to
203 ;; (GF.A GF.B &REST GF.REST &KEY GF.K-X M1.K-Z M1.K-Y M2.K-Q)
205 (deftest gf-interplay
.1
206 (multiple-value-bind (required optional restp rest keyp keys allowp
207 auxp aux morep more-context more-count
)
208 (sb-int:parse-lambda-list
(function-lambda-list #'xuuq
))
209 (and (equal required
'(gf.a gf.b
))
211 (and restp
(eql rest
'gf.rest
))
213 (member 'gf.k-X keys
)
214 (member 'm1.k-Y keys
)
215 (member 'm1.k-Z keys
)
216 (member 'm2.k-Q keys
))
218 (and (not auxp
) (null aux
))
219 (and (not morep
) (null more-context
) (not more-count
))))
222 ;;; Check what happens when there's no explicit DEFGENERIC.
224 (defmethod kroolz (r1 r2
&optional opt
&aux aux
)
225 (declare (ignore r1 r2 opt aux
))
228 (deftest gf-interplay
.2
229 (equal (function-lambda-list #'kroolz
) '(r1 r2
&optional opt
))
232 ;;;; Check correctness of DEFTYPE-LAMBDA-LIST.
234 (&whole w
&environment e r1 r2
&optional o
&rest rest
&key k1 k2 k3
)
235 (declare (ignore w e r1 r2 o rest k1 k2 k3
))
238 (deftest deftype-lambda-list
.1
239 (deftype-lambda-list 'foobar-type
)
240 (&whole w
&environment e r1 r2
&optional o
&rest rest
&key k1 k2 k3
)
243 (deftest deftype-lambda-list
.2
244 (deftype-lambda-list (gensym))
248 ;; ARRAY is a primitive type with associated translator function.
249 (deftest deftype-lambda-list
.3
250 (deftype-lambda-list 'array
)
251 (&optional
(sb-kernel::element-type
'*) (sb-kernel::dimensions
'*))
254 ;; VECTOR is a primitive type that is defined by means of DEFTYPE.
255 (deftest deftype-lambda-list
.4
256 (deftype-lambda-list 'vector
)
257 (&optional sb-kernel
::element-type sb-kernel
::size
)
260 ;;; Test allocation-information
262 (defun tai (x kind info
&key ignore
)
263 (multiple-value-bind (kind2 info2
) (sb-introspect:allocation-information x
)
264 (unless (eq kind kind2
)
265 (error "wanted ~S, got ~S" kind kind2
))
266 (when (not (null ignore
))
267 (setf info2
(copy-list info2
))
270 (setf info
(copy-list info
))
275 (deftest allocation-infromation
.1
276 (tai nil
:heap
'(:space
:static
))
279 (deftest allocation-information
.2
280 (tai t
:heap
'(:space
:static
))
283 (deftest allocation-information
.3
284 (tai 42 :immediate nil
)
287 ;;; Skip the whole damn test on GENCGC PPC -- the combination is just
288 ;;; to flaky for this to make too much sense.
290 (deftest allocation-information
.4
293 ;; FIXME: This is the canonical GENCGC result. On PPC we sometimes get
294 ;; :LARGE T, which doesn't seem right -- but ignore that for now.
295 '(:space
:dynamic
:generation
6 :write-protected t
:boxed t
:pinned nil
:large nil
)
296 :ignore
#+ppc
'(:large
) #-ppc nil
)
299 ;; FIXME: Figure out what's the right cheney-result. SPARC at least
300 ;; has exhibited both :READ-ONLY and :DYNAMIC, which seems wrong.
306 (deftest allocation-information.thread
.1
307 (let ((x (list 1 2 3)))
308 (declare (dynamic-extent x
))
309 (tai x
:stack sb-thread
:*current-thread
*))
315 (let ((x (list 1 2 3)))
316 (declare (dynamic-extent x
))
317 (let ((child (sb-thread:make-thread
319 (sb-introspect:allocation-information x
)))))
320 (equal (list :stack sb-thread
:*current-thread
*)
321 (multiple-value-list (sb-thread:join-thread child
))))))
323 (deftest allocation-information.thread
.2
327 (defun thread-tai2 ()
328 (let* ((sem (sb-thread:make-semaphore
))
330 (child (sb-thread:make-thread
332 (let ((x (list 1 2 3)))
333 (declare (dynamic-extent x
))
335 (sb-thread:wait-on-semaphore sem
)))
339 (equal (list :stack child
)
341 (sb-introspect:allocation-information obj
)))
342 (sb-thread:signal-semaphore sem
)
343 (sb-thread:join-thread child
))))
345 (deftest allocation-information.thread
.3
349 ;;;; Test FUNCTION-TYPE
351 (defun type-equal (typespec1 typespec2
)
352 (or (equal typespec1 typespec2
) ; TYPE= punts on &keywords in FTYPEs.
353 (sb-kernel:type
= (sb-kernel:values-specifier-type typespec1
)
354 (sb-kernel:values-specifier-type typespec2
))))
356 (defmacro interpret
(form)
357 `(let ((sb-ext:*evaluator-mode
* :interpret
))
362 (declaim (ftype (function (integer &optional string
) string
) moon
))
363 (defun moon (int &optional suffix
)
364 (concatenate 'string
(princ-to-string int
) suffix
))
366 (deftest function-type
.1
367 (values (type-equal (function-type 'moon
) (function-type #'moon
))
368 (type-equal (function-type #'moon
)
369 '(function (integer &optional string
)
370 (values string
&rest t
))))
373 (defun sun (x y
&key k1
)
374 (declare (fixnum x y
))
375 (declare (boolean k1
))
376 (declare (ignore x y k1
))
379 (deftest function-type
.2
380 (values (type-equal (function-type 'sun
) (function-type #'sun
))
381 ;; Does not currently work due to Bug #384892. (1.0.31.26)
383 (type-equal (function-type #'sun
)
384 '(function (fixnum fixnum
&key
(:k1
(member nil t
)))
385 (values (member t
) &optional
))))
390 (deftest function-type
.5
393 (values (symbol-name s
))))
394 (type-equal (function-type #'f
)
395 '(function (symbol) (values simple-string
&optional
))))
400 (deftest function-type
.6
406 (type-equal (function-type #'closure
)
407 '(function (fixnum) (values fixnum
&optional
)))))
410 ;; Anonymous functions
412 (deftest function-type
.7
413 (type-equal (function-type #'(lambda (x) (declare (fixnum x
)) x
))
414 '(function (fixnum) (values fixnum
&optional
)))
417 ;; Interpreted functions
420 (deftest function-type
.8
421 (type-equal (function-type (interpret (lambda (x) (declare (fixnum x
)) x
)))
422 '(function (&rest t
) *))
427 (defgeneric earth
(x y
))
429 (deftest function-type
+gfs
.1
430 (values (type-equal (function-type 'earth
) (function-type #'earth
))
431 (type-equal (function-type 'earth
) '(function (t t
) *)))
434 ;; Implicitly created generic functions.
436 ;; (FUNCTION-TYPE 'MARS) => FUNCTION at the moment. (1.0.31.26)
440 (defmethod mars (x y
) (+ x y
))
443 (deftest function-type
+gfs
.2
444 (values (type-equal (function-type 'mars
) (function-type #'mars
))
445 (type-equal (function-type 'mars
) '(function (t t
) *)))
448 ;; DEFSTRUCT created functions
450 ;; These do not yet work because SB-KERNEL:%FUN-NAME does not work on
451 ;; functions defined by DEFSTRUCT. (1.0.35.x)
458 (defstruct (struct (:predicate our-struct-p
)
459 (:copier copy-our-struct
))
462 (deftest function-type
+defstruct
.1
463 (values (type-equal (function-type 'struct-a
)
464 (function-type #'struct-a
))
465 (type-equal (function-type 'struct-a
)
466 '(function (struct) (values fixnum
&optional
))))
469 (deftest function-type
+defstruct
.2
470 (values (type-equal (function-type 'our-struct-p
)
471 (function-type #'our-struct-p
))
472 (type-equal (function-type 'our-struct-p
)
473 '(function (t) (values (member t nil
) &optional
))))
476 (deftest function-type
+defstruct
.3
477 (values (type-equal (function-type 'copy-our-struct
)
478 (function-type #'copy-our-struct
))
479 (type-equal (function-type 'copy-our-struct
)
480 '(function (struct) (values struct
&optional
))))
483 (defstruct (typed-struct :named
(:type list
)
484 (:predicate typed-struct-p
))
487 (deftest function-type
+defstruct
.4
488 (values (type-equal (function-type 'typed-struct-a
)
489 (function-type #'typed-struct-a
))
490 (type-equal (function-type 'typed-struct-a
)
491 '(function (list) (values fixnum
&optional
))))
494 (deftest function-type
+defstruct
.5
495 (values (type-equal (function-type 'typed-struct-p
)
496 (function-type #'typed-struct-p
))
497 (type-equal (function-type 'typed-struct-p
)
498 '(function (t) (values (member t nil
) &optional
))))
505 (defun (setf sun
) (value x y
&key k1
)
506 (declare (boolean value
))
507 (declare (fixnum x y
))
508 (declare (boolean k1
))
509 (declare (ignore x y k1
))
512 (deftest function-type
+setf
.1
513 (values (type-equal (function-type '(setf sun
))
514 (function-type #'(setf sun
)))
515 (type-equal (function-type '(setf sun
))
516 '(function ((member nil t
)
518 &key
(:k1
(member nil t
)))
524 (deftest function-type
+misc
.1
526 (type-equal (function-type #'nullary
)
527 '(function () (values null
&optional
))))