| ... |
... |
@@ -66,8 +66,25 @@ |
|
66
|
66
|
(defstruct (xref-context
|
|
67
|
67
|
(:print-function %print-xref-context)
|
|
68
|
68
|
(:make-load-form-fun :just-dump-it-normally))
|
|
|
69
|
+ ;; The name identifies the program site that originated the
|
|
|
70
|
+ ;; cross-reference and is one of: a symbol naming a global
|
|
|
71
|
+ ;; function; a list (SETF foo); a list (:MACRO foo) for a macro;
|
|
|
72
|
+ ;; a list (:INTERNAL outer inner) for an inner function (FLET,
|
|
|
73
|
+ ;; LABELS, or anonymous lambda); a list (:METHOD foo (specializer
|
|
|
74
|
+ ;; ...)) for a method; the string "Top-Level Form" for a reference
|
|
|
75
|
+ ;; from a top-level form; or a string such as "defun foo" or
|
|
|
76
|
+ ;; "DEFSTRUCT FOO" identifying a reference from compiler-generated
|
|
|
77
|
+ ;; code.
|
|
69
|
78
|
name
|
|
|
79
|
+ ;; The truename (in the sense of *COMPILE-FILE-TRUENAME*) of the
|
|
|
80
|
+ ;; source file the referencing forms were compiled from, or NIL
|
|
|
81
|
+ ;; if compiled from a stream or interactively.
|
|
70
|
82
|
(file *compile-file-truename*)
|
|
|
83
|
+ ;; A list of positive integers identifying the form that contains
|
|
|
84
|
+ ;; the cross-reference. The first integer is the number of the
|
|
|
85
|
+ ;; top-level form in the source file (1-based); subsequent
|
|
|
86
|
+ ;; integers identify nested subforms. Always NIL when FILE is
|
|
|
87
|
+ ;; NIL.
|
|
71
|
88
|
(source-path nil))
|
|
72
|
89
|
|
|
73
|
90
|
(defun %print-xref-context (s stream d)
|
| ... |
... |
@@ -82,6 +99,18 @@ |
|
82
|
99
|
(xref-context-name s)
|
|
83
|
100
|
(xref-context-file s)))))
|
|
84
|
101
|
|
|
|
102
|
+(setf (documentation 'xref-context-name 'function)
|
|
|
103
|
+ _N"Return the name slot of an xref-context, identifying the program
|
|
|
104
|
+site that originated the cross-reference.")
|
|
|
105
|
+
|
|
|
106
|
+(setf (documentation 'xref-context-file 'function)
|
|
|
107
|
+ _N"Return the source file truename of an xref-context, or NIL if
|
|
|
108
|
+the code was not compiled from a file.")
|
|
|
109
|
+
|
|
|
110
|
+(setf (documentation 'xref-context-source-path 'function)
|
|
|
111
|
+ _N"Return the source-path of an xref-context, a list of positive
|
|
|
112
|
+integers identifying the form that contains the cross-reference.")
|
|
|
113
|
+
|
|
85
|
114
|
|
|
86
|
115
|
;; program contexts where a globally-defined function may be called at runtime
|
|
87
|
116
|
(defvar *who-calls* (make-hash-table :test #'eq))
|
| ... |
... |
@@ -153,21 +182,30 @@ may be referenced at runtime." |
|
153
|
182
|
;; WHO-BINDS -- interface
|
|
154
|
183
|
;;
|
|
155
|
184
|
(defun who-binds (global-variable)
|
|
156
|
|
- "Return a list of those program contexts where GLOBAL-VARIABLE may
|
|
157
|
|
-be bound at runtime."
|
|
|
185
|
+ "Return a list of those program contexts where GLOBAL-VARIABLE may be bound at runtime.
|
|
|
186
|
+
|
|
|
187
|
+ A binding is recorded whenever the compiler emits a special binding
|
|
|
188
|
+ for the form -- including cases that look lexical in source, such as (LET (FOO)
|
|
|
189
|
+ ...), if FOO has been proclaimed special earlier in the compiling
|
|
|
190
|
+ image. WHO-BINDS reflects what the compiler did, not what the source
|
|
|
191
|
+ text appears to say."
|
|
158
|
192
|
(declare (type symbol global-variable))
|
|
159
|
193
|
(gethash global-variable *who-binds*))
|
|
160
|
194
|
|
|
161
|
195
|
;; WHO-SETS -- interface
|
|
162
|
196
|
;;
|
|
163
|
197
|
(defun who-sets (global-variable)
|
|
164
|
|
- "Return a list of those program contexts where GLOBAL-VARIABLE may
|
|
165
|
|
-be set at runtime."
|
|
|
198
|
+ "Return a list of those program contexts where GLOBAL-VARIABLE may be
|
|
|
199
|
+ set at runtime."
|
|
166
|
200
|
(declare (type symbol global-variable))
|
|
167
|
201
|
(gethash global-variable *who-sets*))
|
|
168
|
202
|
|
|
169
|
203
|
|
|
170
|
204
|
(defun who-macroexpands (macro)
|
|
|
205
|
+ "Return a list of those program contexts where MACRO may be expanded at
|
|
|
206
|
+ compile time. The caller name in each context is the form whose
|
|
|
207
|
+ compilation triggered the macroexpansion (a function, a method, or
|
|
|
208
|
+ the string \"Top-Level Form\")."
|
|
171
|
209
|
(declare (type symbol macro))
|
|
172
|
210
|
(gethash macro *who-macroexpands*))
|
|
173
|
211
|
|
| ... |
... |
@@ -177,22 +215,35 @@ be set at runtime." |
|
177
|
215
|
;; WHO-SUBCLASSES -- interface
|
|
178
|
216
|
;;
|
|
179
|
217
|
(defun who-subclasses (class)
|
|
|
218
|
+ "Return the list of direct subclasses of CLASS. Only direct subclasses
|
|
|
219
|
+ are returned; transitive subclasses are not. CLASS is a class
|
|
|
220
|
+ metaobject, not a class-name symbol; use FIND-CLASS to convert a
|
|
|
221
|
+ name."
|
|
180
|
222
|
(pcl::class-direct-subclasses class))
|
|
181
|
223
|
|
|
182
|
224
|
;; WHO-SUPERCLASSES -- interface
|
|
183
|
225
|
;;
|
|
184
|
226
|
(defun who-superclasses (class)
|
|
|
227
|
+ "Return the list of direct superclasses of CLASS. Only direct
|
|
|
228
|
+ superclasses are returned; transitive superclasses are not. CLASS
|
|
|
229
|
+ is a class metaobject, not a class-name symbol; use FIND-CLASS to
|
|
|
230
|
+ convert a name."
|
|
185
|
231
|
(pcl::class-direct-superclasses class))
|
|
186
|
232
|
|
|
187
|
233
|
;; WHO-SPECIALIZES -- interface
|
|
188
|
234
|
;;
|
|
189
|
|
-;; generic functions defined for this class
|
|
190
|
235
|
(defun who-specializes (class)
|
|
|
236
|
+ "Return the list of methods that specialize directly on CLASS. CLASS is
|
|
|
237
|
+ a class metaobject, not a class-name symbol; use FIND-CLASS to
|
|
|
238
|
+ convert a name."
|
|
191
|
239
|
(pcl::specializer-direct-methods class))
|
|
192
|
240
|
|
|
193
|
241
|
;; Go through all the databases and remove entries from that that
|
|
194
|
242
|
;; reference the given Namestring.
|
|
195
|
243
|
(defun invalidate-xrefs-for-namestring (namestring)
|
|
|
244
|
+ "Remove from every cross-reference database all xref-contexts whose
|
|
|
245
|
+ source file is NAMESTRING. Used to clear stale entries before
|
|
|
246
|
+ recompiling a file."
|
|
196
|
247
|
(labels ((matching-context (ctx)
|
|
197
|
248
|
(equal namestring (if (pathnamep (xref-context-file ctx))
|
|
198
|
249
|
(namestring (xref-context-file ctx))
|
| ... |
... |
@@ -212,6 +263,17 @@ be set at runtime." |
|
212
|
263
|
;; return a list of all the matches. Each element of the list is a
|
|
213
|
264
|
;; list of the target followed by the entries.
|
|
214
|
265
|
(defun find-xrefs-for-pathname (db pathname)
|
|
|
266
|
+ "Return entries from cross-reference database DB whose source file
|
|
|
267
|
+ matches PATHNAME. DB is one of :CALLS, :CALLED, :REFERENCES,
|
|
|
268
|
+ :BINDS, :SETS, or :MACROEXPANDS.
|
|
|
269
|
+
|
|
|
270
|
+ Each entry is a two-element list (TARGET CONTEXTS), where TARGET is
|
|
|
271
|
+ the the symbol (or (SETF foo) form for setf functions) being
|
|
|
272
|
+ cross-referenced — a function name for :CALLS, :CALLED, and
|
|
|
273
|
+ :MACROEXPANDS, a variable name for :REFERENCES, :BINDS, and :SETS.
|
|
|
274
|
+ and CONTEXTS is the list of xref-contexts (the program sites
|
|
|
275
|
+ originating the cross-reference) for TARGET whose file slot matches
|
|
|
276
|
+ PATHNAME."
|
|
215
|
277
|
(let ((entries '()))
|
|
216
|
278
|
(maphash #'(lambda (target contexts)
|
|
217
|
279
|
(let ((matches '()))
|