DRef Manual
Table of Contents
- 1 Links and Systems
- 2 Introduction
- 3 References
- 4
dtypes - 5 Listing Definitions
- 6 Basic Operations
- 7 Basic Locative Types
- 8 Extending DRef
[in package DREF]
1 Links and Systems
Here is the official repository and the HTML documentation for the latest version.
DRef is bundled in the same repository with PAX, the documentation system.
- [system] "dref"
- Version: 0.4.4
- Description: Reify definitions, provide portable access to docstrings and source locations in an extensible framework.
- Long Description:
defundefines a first-class object: afunction(01).defvardoes not. This library provides a way to refer to all definitions and smooths over the differences between implementations. This system has minimal dependencies. It autoloads thedref/fullasdf:system, which depends Alexandria and Swank. - Licence: MIT, see COPYING.
- Author: Gábor Melis
- Mailto: mega@retes.hu
- Homepage: http://github.com/melisgl/mgl-pax/tree/master/dref
- Bug tracker: https://github.com/melisgl/mgl-pax/issues
- Source control: GIT
- Depends on: autoload, mgl-pax-bootstrap, named-readtables, pythonic-string-reader
- Defsystem depends on: mgl-pax.asdf
- [system] "dref/full"
Description:
dref(01) with everything loaded. There should be no need to explicitly load this system (or depend on it) as it is autoloaded as necessary by all publicly accessible functionality indref.However, to get the dependencies, install this system.
Depends on: alexandria, dref, swank(?)
Defsystem depends on: mgl-pax.asdf
2 Introduction
What if definitions were first-class objects?
Some defining forms do not create first-class
objects. For example, defun creates
function objects, but defvar does not create variable
objects as no such thing exists. The main purpose of this library is
to fill this gap with the introduction of dref objects:
(defvar *my-var* nil
"This is my var.")
(dref '*my-var* 'variable)
==> #<DREF *MY-VAR* VARIABLE>
drefs just package up a name (*my-var*) and a
locative (variable) then check that the definition
actually exists:
(dref 'junk 'variable)
.. debugger invoked on LOCATE-ERROR:
.. Could not locate JUNK VARIABLE.
The Basic Operations on definitions in DRef are arglist, docstring
and source-location.
(docstring (dref '*my-var* 'variable))
=> "This is my var."
For definitions associated with objects, the definition can be
located from the object:
(locate #'print)
==> #<DREF PRINT FUNCTION>
These objects designate their definitions, so (docstring #'print)
works. Extending DRef and these operations is possible through
Defining Locative Types. It is also possible to define
new operations. For example, PAX makes
pax:document extensible through pax:document-object*.
Finally, existing definitions can be queried with definitions and
dref-apropos:
(definitions 'dref-ext:arglist*)
==> (#<DREF ARGLIST* GENERIC-FUNCTION>
--> #<DREF ARGLIST* (METHOD (MGL-PAX::GO-DREF))>
--> #<DREF ARGLIST* (METHOD (LAMBDA-DREF))>
--> #<DREF ARGLIST* (METHOD (TYPE-DREF))>
--> #<DREF ARGLIST* (METHOD (METHOD-DREF))>
--> #<DREF ARGLIST* (METHOD (FUNCTION-DREF))>
--> #<DREF ARGLIST* (METHOD (COMPILER-MACRO-DREF))>
--> #<DREF ARGLIST* (METHOD (MACRO-DREF))>
--> #<DREF ARGLIST* (METHOD (SETF-DREF))> #<DREF ARGLIST* (METHOD (T))>
--> #<DREF ARGLIST* (METHOD (DREF))>
--> #<DREF ARGLIST* (UNKNOWN
--> (DECLAIM ARGLIST*
--> FTYPE))>)
(dref-apropos 'locate-error :package :dref)
==> (#<DREF LOCATE-ERROR CONDITION> #<DREF LOCATE-ERROR FUNCTION>)
(dref-apropos "ate-err" :package :dref :external-only t)
==> (#<DREF LOCATE-ERROR CONDITION> #<DREF LOCATE-ERROR FUNCTION>)
3 References
After the Introduction, here we get into the details. Of special interest are:
The
xreffunction to construct an arbitrary reference without any checking of validity.locateanddrefto look up the definition of an object (e.g#'print) or a reference (e.g.(xref 'print 'function)).resolveto find the first-class (non-xref) object the definition refers to, if any.
The Basic Operations (arglist, docstring, source-location) know how to
deal with references (discussed in the Extending DRef).
-
An
xref(cross-reference) is a reference. It may represent some kind of definition of its name in the context given by its locative. The definition may not exist and the locative may even be invalid. The subclassdrefrepresents definitions that exist.
[function] xref name locative
A shorthand for
(make-instance 'xref :name name :locative locative)to createxrefobjects. It does no error checking: thelocative-typeoflocative-typeneed not be defined, and thelocative-argsneed not be valid. Uselocateor thedreffunction to createdrefobjects.
[function] xref= xref1 xref2
See if
xref1andxref2have the samexref-nameandxref-locativeunderequal. Comparing like this makes most sense fordrefs. However, twoxrefs different underxref=may denote the samedrefs.
-
drefs can be thought of as definitions that actually exist, although changes in the system can invalidate them (for example, adrefto a function definition can be invalidated byfmakunbound).drefs must be created withlocateor thedreffunction.Two
drefs created in the same dynamic environment denote the same thing if and only if they arexref=.
[function] locate object &optional (errorp t)
Return a
drefrepresenting the definition ofobject.objectmust be a supported first-class object, adref, or anxref:(locate #'print) ==> #<DREF PRINT FUNCTION>(locate (locate #'print)) ==> #<DREF PRINT FUNCTION>(locate (xref 'print 'function)) ==> #<DREF PRINT FUNCTION>When
objectis adref, it is simply returned.Else, a
locate-error(01) is signalled ifobjectis anxrefwith an invalid locative, or if no corresponding definition is found. Iferrorpisnil, thennilis returned instead.(locate (xref 'no-such-function 'function)) .. debugger invoked on LOCATE-ERROR: .. Could not locate NO-SUCH-FUNCTION FUNCTION. .. NO-SUCH-FUNCTION does not name a function.(locate (xref 'print '(function xxx))) .. debugger invoked on LOCATE-ERROR: .. Could not locate PRINT #'XXX. .. Bad arguments (XXX) for locative FUNCTION with lambda list NIL.(locate "xxx") .. debugger invoked on LOCATE-ERROR: .. Could not locate "xxx".Use the
xreffunction to construct anxrefwithout error checking.See Extending
locate.
[function] dref name locative &optional (errorp t)
Shorthand for
(locate (xref name locative) errorp).
[function] resolve object &optional (errorp t)
If
objectis anxref, then return the first-class object associated with its definition if any. Returnobjectif it's not anxref. Thus, the value returned is never anxref. The second return value is whether resolving succeeded.(resolve (dref 'print 'function)) ==> #<FUNCTION PRINT> => T(resolve #'print) ==> #<FUNCTION PRINT> => TIf
objectis anxref, and the definition for it cannot belocated, thenlocate-error(01) is signalled.(resolve (xref 'undefined 'variable)) .. debugger invoked on LOCATE-ERROR: .. Could not locate UNDEFINED VARIABLE.If there is a definition, but there is no first-class object corresponding to it, then
resolve-error(01) is signalled ornilis returned depending onerrorp:(resolve (dref '*print-length* 'variable)) .. debugger invoked on RESOLVE-ERROR: .. Could not resolve *PRINT-LENGTH* VARIABLE.(resolve (dref '*print-length* 'variable) nil) => NIL => NILresolveis a partial inverse oflocate: if adrefisresolveable, thenlocateing the object it resolves to recovers thedrefequivalent to the original (xref=and of the same type but noteq).Can be extended via
resolve*.
[condition] locate-error error
Signalled by
locatewhen the definition cannot be found, anderrorpis true.
[condition] resolve-error error
Signalled by
resolvewhen the object defined cannot be returned, anderrorpis true.
3.1 Dissecting References
[reader] xref-locative xref (:locative)
The locative of the reference.
The locative is normalized by replacing single-element lists with their only element:
(xref 'print 'function) ==> #<XREF PRINT FUNCTION>(xref 'print '(function)) ==> #<XREF PRINT FUNCTION>
-
The same as
xref-locative, but only works ondrefs. Use it as a statement of intent.
-
The object from which
locateconstructed thisdref.dref-originmay have presentation arguments, which are not included inlocative-argsas is the case with theinitformargument of thevariablelocative:(dref '*standard-output* '(variable "see-below")) ==> #<DREF *STANDARD-OUTPUT* VARIABLE>(dref-origin (dref '*standard-output* '(variable "see-below"))) ==> #<XREF *STANDARD-OUTPUT* (VARIABLE "see-below")>The
initformargument overrides the global binding of*standard-output*when it'spax:documented:(first-line (pax:document (dref '*standard-output* '(variable "see-below")) :stream nil)) => "- [variable] *STANDARD-OUTPUT* \"see-below\""
[function] locative-type locative
Return locative type of the locative
locative. This is the first element oflocativeif it's a list. If it's a symbol, it's that symbol itself.
[function] locative-args locative
Return the
restof locativelocativeif it's a list. If it's a symbol, then returnnil. See locative.
The following convenience functions are compositions of
{locative-type, locative-args} and {xref-locative,
dref-locative}.
3.2 References Glossary
-
A reference is a name plus a locative, and it identifies a possible definition. References are of class
xref. When a reference is adref, it may also be called a definition.
-
A definition is a reference that identifies a concrete definition. Definitions are of class
dref. A definitionresolves to the first-class object associated with the definition if such a thing exists, andlocateon this object returns the canonicaldrefobject that's unique underxref=.The kind of a definition is given by its locative type. There is at most one definition for any given name and locative type. Equivalently, there can be no two definitions of the same
dref-nameanddref-locative-typebut differentdref-locative-args.
-
Names are symbols, strings and nested lists of the previous, which name functions, types, packages, etc. Together with locatives, they form references.
-
Locatives specify a type of definition such as
functionorvariable. Together with names, they form references.In their compound form, locatives may have arguments (see
locative-args) as in(method (number)). In fact, their atomic form is shorthand for the common no-argument case: that is,functionis equivalent to(function).A locative is valid if it names an existing locative type and its
locative-argsmatch that type's lambda-list (seedefine-locative-type).(arglist (dref 'method 'locative)) => (&REST QUALIFIERS-AND-SPECIALIZERS) => :DESTRUCTURINGSee
xref-locativeanddref-locative.
-
The locative type is the part of a locative that identifies what kind definition is being referred to. This is always a symbol.
Locative types are defined with
define-locative-typeordefine-pseudo-locative-type. See Basic Locative Types for the list locative types built into DRef, and PAX Locatives for those in PAX.Also, see
locative-type,xref-locative-type,dref-locative-type, Defining Locative Types.
-
references may have arguments (see Defining Locative Types) that do not affect the behaviour of
locateand the Basic Operations, but which may be used for other, "presentation" purposes. For example, thevariablelocative'sinitformargument is used for presentation bypax:document. Presentation arguments are available viadref:dref-originbut do not feature indref-locativeto ensure the uniqueness of the definition underxref=.
4 dtypes
dtypes are to Lisp types what locative types are to classes.
A dtype is either
a locative type such as
function,typeandclhs, ora full locative such as
(method (number))and(clhs section), ornil(the emptydtype) andt(that encompasses alllisp-locative-types), ornamed with
define-dtype(such aspseudoandtop), ora
satisfiesform with the name of a function that takes a single definition as its argument.
dtypes are used in definitions and dref-apropos to filter the set of
definitions as in
(definitions 'print :dtype '(not unknown))
==> (#<DREF PRINT (CLHS FUNCTION)> #<DREF PRINT FUNCTION>)
(dref-apropos "type specifier" :dtype 'pseudo)
==> (#<DREF "1.4.4.6" #1=(CLHS SECTION)> #<DREF "1.4.4.6.1" #1#>
--> #<DREF "1.4.4.6.2" #1#> #<DREF "1.4.4.6.3" #1#>
--> #<DREF "1.4.4.6.4" #1#> #<DREF "4.2.3" #1#>
--> #<DREF "atomic type specifier" #2=(CLHS GLOSSARY-TERM)>
--> #<DREF "compound type specifier" #2#>
--> #<DREF "derived type specifier" #2#> #<DREF "type specifier" #2#>)
[macro] define-dtype name lambda-list &body body
Like
deftype, but it may expand into otherdtypes.The following example defines
method*as the locativemethodwithout its direct locative subtypes.(define-dtype method* () '(and method (not reader) (not writer)))
-
This is the top of the
dtypehierarchy, much liketfor Lisp types. It expands to (ortpseudo). Whiletmatches every normal Lisp object and objectless definitions present in the running Lisp (seelisp-locative-types),topmatches even pseudo definitions (seepseudo-locative-types).
-
This is the union of all
pseudo-locative-types. It expands to(or ,@(pseudo-locative-types)).
[function] dtypep dref dtype
See if
drefis ofdtype.Atomic locatives: If
dtypeis a locative type, then it matches definitions with that locative type and its locative subtypes.Because
constantis defined withvariableamong itslocative-supertypes:(dtypep (dref 'pi 'constant) 'variable) => T(dtypep (dref 'number 'class) 'type) => TIt is an error if
dtypeis anatom(01) but is not a locative type, but (the empty) argument list of bare locative types are not checked even if having no arguments makes them invalid locatives.Compound locatives: Locatives in their compound form are validated and must match exactly (under
equal, as inxref=).(defparameter *d* (dref 'dref* '(method (t t t)))) (defparameter *d2* (dref 'dref* '(method :around (t t t)))) (dtypep *d* 'method) => T (dtypep *d* '(accessor)) .. debugger invoked on SIMPLE-ERROR: .. Bad arguments NIL for locative ACCESSOR with lambda list (CLASS-NAME). (dtypep *d* '(method (t t t))) => T (dtypep *d2* '(method (t t t))) => NILdtypemay be constructed withand,orandnotfrom Lisp types, locative types, full locatives and nameddtypes:(dtypep (dref 'locate-error 'condition) '(or condition class)) => T (dtypep (dref nil 'type) '(and type (not class))) => TFor
(member &rest objs), each ofobjs islocated anddrefis matched against them withxref=:(dtypep (locate #'print) `(member ,#'print)) => TFor
(satisfies pred), the predicatepredis funcalled withdref.dtypemay be named bydefine-dtype:(dtypep (locate #'car) 'top) => T
5 Listing Definitions
[function] definitions name &key (dtype t)
List all definitions of
namethat are ofdtypeasdrefs.Just as
(dref name locative)returns the canonical definition, thedref-names of returned bydefinitionsmay be different fromname:(definitions "PAX") ==> (#<DREF "MGL-PAX" PACKAGE>)(definitions 'mgl-pax) ==> (#<DREF "mgl-pax" ASDF/SYSTEM:SYSTEM> #<DREF "MGL-PAX" PACKAGE>)Similarly,
dref-locative-typemay be more made more specific:(definitions 'dref:locate-error :dtype 'type) ==> (#<DREF LOCATE-ERROR CONDITION>)Can be extended via
map-definitions-of-name.
[function] dref-apropos name &key package external-only case-sensitive (dtype t)
Return a list of
drefs corresponding to existing definitions that match the various arguments. First,(dref-apropos nil)lists all definitions in the running Lisp and maybe more (e.g.mgl-pax:clhs). Arguments specify how the list of definitions is filtered.dref-apropositself is similar tocl:apropos-list, butit finds definitions not
symbols,it supports an extensible definition types, and
filtering based on them.
PAX has a live browsing frontend.
Roughly speaking, when
nameorpackageis asymbol, they must match the whole name of the definition:(dref-apropos 'method :package :dref :external-only t) ==> (#<DREF METHOD CLASS> #<DREF METHOD LOCATIVE>)On the other hand, when
nameorpackageis astring(01), they are matched as substrings to the definition's nameprinc-to-stringed:(dref-apropos "method" :package :dref :external-only t) ==> (#<DREF SETF-METHOD LOCATIVE> #<DREF METHOD CLASS> --> #<DREF METHOD LOCATIVE> #<DREF METHOD-COMBINATION CLASS> --> #<DREF METHOD-COMBINATION LOCATIVE>)Definitions that are not of
dtype(seedtypep) are filtered out:(dref-apropos "method" :package :dref :external-only t :dtype 'class) ==> (#<DREF METHOD CLASS> #<DREF METHOD-COMBINATION CLASS>)When
packageis:none, only non-symbol names are matched:(dref-apropos "dref" :package :none) ==> (#<DREF "DREF" PACKAGE> #<DREF "DREF-EXT" PACKAGE> --> #<DREF "DREF-TEST" PACKAGE> #<DREF "dref" ASDF/SYSTEM:SYSTEM> --> #<DREF "dref/full" ASDF/SYSTEM:SYSTEM> --> #<DREF "dref/test" ASDF/SYSTEM:SYSTEM> --> #<DREF "dref/test-autoload" ASDF/SYSTEM:SYSTEM>)The exact rules of filtering are as follows. Let
cbe the name of the candidate definition from the list of all definitions that we are matching against the arguments and denote its string representation(princ-to-string c)withp. Note thatprinc-to-stringdoes not print the package of symbols. We say that two strings match ifcase-sensitiveisniland they areequalp, orcase-sensitiveis true and they areequal.case-sensitiveaffects substring comparisons too.If
nameis asymbol, then itssymbol-namemust matchp.If
nameis astring, then it must be a substring ofp.If
packageis:any, thencmust be asymbol.If
packageis:none, thencmust not be asymbol.If
packageis notnil,:anyor:none, thencmust be a symbol.If
packageis apackage, it must beeqto thesymbol-packageofc.If
packageis asymbolother thannil,:anyand:none, then itssymbol-namemust match thepackage-nameor one of thepackage-nicknamesofsymbol-packageofc.If
packageis astring, then it must be a substring of thepackage-nameofsymbol-packageofc.If
external-onlyandcis a symbol, thencmust be external in a matching package.dtypematches candidate definitiondif(dtypep d dtype).
Can be extended via MAP-REFERENCES-OF-TYPE and
map-definitions-of-name.
[glossary-term] reverse definition order
Lists of locative types and aliases are sometimes in reverse order of the time of their definition. This order is not affected by redefinition, regardless of whether it's by
define-locative-type,define-pseudo-locative-type,define-symbol-locative-typeordefine-locative-alias.
-
Return a list of non-alias locative types. This is the
unionoflisp-locative-typesandpseudo-locative-types, which is the set of constituents of thedtypetop.This list is in reverse definition order.
[function] lisp-locative-types
Return the locative types that correspond to Lisp definitions, which typically have
source-location. These are defined withdefine-locative-typeanddefine-symbol-locative-typeand are the constituents ofdtypet.This list is in reverse definition order.
[function] pseudo-locative-types
Return the locative types that correspond to non-Lisp definitions. These are the ones defined with
define-pseudo-locative-typeand are the constituents ofdtypepseudo.This list is in reverse definition order.
-
Return the list of locatives aliases, defined with
define-locative-alias.This list is in reverse definition order.
6 Basic Operations
The following functions take a single argument, which may be a
dref, or an object denoting its own definition (see
locate).
[function] arglist object
Return the arglist of the definition of
objectornilif the arglist cannot be determined.The second return value indicates whether the arglist has been found. As the second return value,
:ordinaryindicates an ordinary lambda list,:macroa macro lambda list,:deftypea deftype lambda list, and:destructuringa destructuring lambda list. Other non-nilvalues are also allowed.(arglist #'arglist) => (OBJECT) => :ORDINARY(arglist (dref 'define-locative-type 'macro)) => (LOCATIVE-TYPE-AND-LAMBDA-LIST LOCATIVE-SUPERTYPES &OPTIONAL DOCSTRING DREF-DEFCLASS-FORM) => :MACRO(arglist (dref 'method 'locative)) => (&REST QUALIFIERS-AND-SPECIALIZERS) => :DESTRUCTURINGThis function supports
macros,compiler-macros,setffunctions,functions,generic-functions,methods,types,locatives. Note thatarglistdepends on the quality ofswank-backend:arglist. With the exception of SBCL, which has perfect support, all Lisp implementations have minor omissions:deftypelambda lists on ABCL, AllegroCL, CLISP, CCL, CMUCL, ECL;default values in
macrolambda lists on AllegroCL;various edge cases involving traced functions.
Can be extended via
arglist*
[function] docstring object
Return the docstring from the definition of
object. As the second value, return the*package*that was in effect when the docstring was installed ornilif it cannot be determined (this is used bypax:documentwhen Parsing the docstring). This function is similar in purpose tocl:documentation.Note that some locative types such as
asdf:systems anddeclarations have no docstrings, and some Lisp implementations do not record all docstrings. The following are known to be missing:compiler-macrodocstrings on ABCL, AllegroCL, CCL, ECL;method-combinationdocstrings on ABCL, AllegroCL.
Can be extended via
docstring*.
[function] source-location object &key error
Return the Swank source location for the defining form of
object.The returned Swank location object is to be accessed only through the Source Locations API or to be passed to e.g Slime's
slime-goto-source-location.If no source location was found,
if
errorisnil, then returnnil;if
erroris:error, then return a list of the form(:error <error-message>)suitable forslime-goto-source-location;if
errorist, then signal anerrorcondition with the same error message as in the previous case.
Note that the availability of source location information varies greatly across Lisp implementations.
Can be extended via
source-location*.
7 Basic Locative Types
The following are the locative types supported out of the
box. As all locative types, they are named by symbols. When there is
a CL type corresponding to the reference's locative type, the
references can be resolved to a unique object as is the case in
(resolve (dref 'print 'function))
==> #<FUNCTION PRINT>
=> T
Even if there is no such CL type, the arglist, the docstring, and
the source-location of the defining form is usually recorded unless
otherwise noted.
The basic locative types and their inheritance structure is loosely
based on the doc-type argument of cl:documentation.
7.1 Locatives for Variables
[locative] variable &optional initform
- Direct locative subtypes: glossary-term, section, constant
Refers to a global special variable.
initform, or if not specified, the global value of the variable is to be used for presentation.(dref '*print-length* 'variable) ==> #<DREF *PRINT-LENGTH* VARIABLE>variablereferences do notresolve.
[locative] constant &optional initform
- Direct locative supertypes: variable
Refers to a constant variable defined with
defconstant.initform, or if not specified, the value of the constant is included in the documentation. Theconstantlocative is like thevariablelocative, but it also checks that its object isconstantp.constantreferences do notresolve.
7.2 Locatives for Macros
-
- Direct locative subtypes: setf-method, setf-function
Refers to a setf expander (see
defsetfanddefine-setf-expander).Setf functions (e.g.
(defun (setf name) ...)or the same withdefgeneric) are handled by thesetf-function,setf-generic-function, andsetf-methodlocatives.setfexpander references do notresolve.
-
Refers to a global macro, typically defined with
defmacro, or to a special operator.macroreferences resolve to themacro-functionof theirnameor signalresolve-error(01) if that'snil.
-
Refers to a global symbol macro, defined with
define-symbol-macro. Note that sincedefine-symbol-macrodoes not support docstrings, PAX defines methods on thedocumentationgeneric function specialized on(doc-type (eql 'symbol-macro)).(define-symbol-macro my-mac 42) (setf (documentation 'my-mac 'symbol-macro) "This is MY-MAC.") (documentation 'my-mac 'symbol-macro) => "This is MY-MAC."symbol-macroreferences do notresolve.
-
- Direct locative subtypes: setf-compiler-macro
Refers to a
compiler-macro-function, typically defined withdefine-compiler-macro.
[locative] setf-compiler-macro
- Direct locative supertypes: compiler-macro
Refers to a compiler macro with a setf function name.
setf-compiler-macroreferences do notresolve.
7.3 Locatives for Functions and Methods
-
- Direct locative subtypes: structure-accessor, setf-function, generic-function
Refers to a global function, typically defined with
defun. The name must be a function name. It is also allowed to referencegeneric-functions asfunctions:(dref 'docstring 'function) ==> #<DREF DOCSTRING FUNCTION>
-
Direct locative subtypes: structure-accessor, setf-generic-function
Refers to a global
function(01) with a setf function name.(defun (setf ooh) ()) (locate #'(setf ooh)) ==> #<DREF OOH SETF-FUNCTION> (dref 'ooh 'setf-function) ==> #<DREF OOH SETF-FUNCTION> (dref '(setf ooh) 'function) ==> #<DREF OOH SETF-FUNCTION>
-
Direct locative supertypes: function
Direct locative subtypes: setf-generic-function
Refers to a
generic-function, typically defined withdefgeneric. The name must be a function name.
[locative] setf-generic-function
- Direct locative supertypes: generic-function, setf-function
Refers to a global
generic-functionwith a setf function name.(defgeneric (setf oog) ()) (locate #'(setf oog)) ==> #<DREF OOG SETF-GENERIC-FUNCTION> (dref 'oog 'setf-function) ==> #<DREF OOG SETF-GENERIC-FUNCTION> (dref '(setf oog) 'function) ==> #<DREF OOG SETF-GENERIC-FUNCTION>
[locative] method &rest qualifiers-and-specializers
- Direct locative subtypes: writer, reader, setf-method
Refers to a
method. name must be a function name.method-qualifiers-and-specializershas the form(<QUALIFIER>* <SPECIALIZERS>)For example, the method
(defgeneric foo-gf (x y z) (:method :around (x (y (eql 'xxx)) (z string)) (values x y z)))can be referred to as
(dref 'foo-gf '(method :around (t (eql xxx) string))) ==> #<DREF FOO-GF (METHOD :AROUND (T (EQL XXX) STRING))>methodis notexportable-locative-type-p.
[locative] setf-method &rest method-qualifiers-and-specializers
Refers to a
methodof asetf-generic-function.(defgeneric (setf oog) (v) (:method ((v string)))) (locate (find-method #'(setf oog) () (list (find-class 'string)))) ==> #<DREF OOG (SETF-METHOD (STRING))> (dref 'oog '(setf-method (string))) ==> #<DREF OOG (SETF-METHOD (STRING))> (dref '(setf oog) '(method (string))) ==> #<DREF OOG (SETF-METHOD (STRING))>
-
Refers to a
method-combination, defined withdefine-method-combination.method-combinationreferences do notresolve.
[locative] reader class-name
Refers to a
:readermethod in adefclass:(defclass foo () ((xxx :reader foo-xxx))) (dref 'foo-xxx '(reader foo)) ==> #<DREF FOO-XXX (READER FOO)>
[locative] writer class-name
Like
accessor, but refers to a:writermethod in adefclass.
[locative] accessor class-name
- Direct locative supertypes: reader, writer, setf-method
Refers to an
:accessorin adefclass.An
:accessorindefclasscreates a reader and a writer method. Somewhat arbitrarily,accessorreferencesresolveto the writer method but can belocated with either.
[locative] structure-accessor &optional structure-class-name
- Direct locative supertypes: setf-function, function
Refers to an accessor function generated by
defstruct. Alocate-errorcondition is signalled if the wrongstructure-class-nameis provided.Note that there is no portable way to detect structure accessors, and on some platforms,
(locate #'my-accessor),definitionsanddref-aproposwill returnfunction(01) references instead. On such platforms,structure-accessorreferences do notresolve.
7.4 Locatives for Types and Declarations
-
- Direct locative subtypes: class
This locative can refer to types and classes and conditions, simply put, to things defined by
deftype,defclassanddefine-condition.(deftype my-type () t) (dref 'my-type 'type) ==> #<DREF MY-TYPE TYPE>(dref 'xref 'type) ==> #<DREF XREF CLASS>(dref 'locate-error 'type) ==> #<DREF LOCATE-ERROR CONDITION>typereferences do notresolve.
-
- Direct locative supertypes: class
Refers to a
structure-class, typically defined withdefstruct.
-
Refers to a declaration, used in
declare,declaimandproclaim.User code may also define new declarations with CLTL2 functionality, but there is currently no way to provide a docstring, and their
arglistis alwaysnil.(cl-environments:define-declaration my-decl (&rest things) (values :declare (cons 'foo things)))declarationreferences do notresolve.Also,
source-locationon declarations currently only works on SBCL.
7.5 Locatives for the Condition System
-
- Direct locative supertypes: class
Although
conditionis notsubtypepofclass, actual condition objects are commonly instances of a condition class that is a CLOS class. HyperSpec ISSUE:CLOS-CONDITIONS and ISSUE:CLOS-CONDITIONS-AGAIN provide the relevant history.Whenever a
classdenotes acondition, itsdref-locative-typewill becondition:(dref 'locate-error 'class) ==> #<DREF LOCATE-ERROR CONDITION>
-
A locative to refer to the definition of a restart defined by
define-restart.
[macro] define-restart symbol lambda-list &body docstring
Associate a definition with the name of a restart, which must be a symbol.
lambda-listshould be what calls like(invoke-restart '<symbol> ...)must conform to, but this not enforced.PAX "defines" standard CL restarts such as
use-value(01) withdefine-restart:(first-line (source-location-snippet (source-location (dref 'use-value 'restart)))) => "(define-restart use-value (value)"Note that while there is a
cl:restartclass, its instances have no docstring or source location.
7.6 Locatives for Packages and Readtables
-
Refers to an already loaded
asdf:system(those inasdf:registered-systems). The name may be anythingasdf:find-systemsupports.asdf:systemis notexportable-locative-type-p.
-
Refers to a
package, defined bydefpackageormake-package. The name may be anythingfind-packagesupports.packageis notexportable-locative-type-p.
-
Refers to a named
readtabledefined withnamed-readtables:defreadtable, which associates a global name and a docstring with the readtable object. The name may be anythingfind-readtablesupports.readtablereferencesresolvetofind-readtableon their name.
7.7 Locatives for Unknown Definitions
[locative] unknown dspec
This locative type allows PAX to work in a limited way with definition types it doesn't know.
unknowndefinitions come fromdefinitions, which usesswank/backend:find-definitions. The following examples show PAX stuffing the Swank dspec(:define-alien-type double-float)into anunknownlocative on SBCL.(definitions 'double-float) ==> (#<DREF DOUBLE-FLOAT CLASS> --> #<DREF DOUBLE-FLOAT (UNKNOWN (:DEFINE-ALIEN-TYPE DOUBLE-FLOAT))>)(dref 'double-float '(unknown (:define-alien-type double-float))) ==> #<DREF DOUBLE-FLOAT (UNKNOWN (:DEFINE-ALIEN-TYPE DOUBLE-FLOAT))>arglistanddocstringreturnnilforunknowns, butsource-locationworks.
7.8 Locatives for DRef Constructs
-
- Direct locative subtypes: locative
Locative for
dtypes defined withdefine-dtypeandlocativetypes.dtypeis tolocativeastypeis toclass.The
topof thedtypehierarchy:(dref 'top 'dtype) ==> #<DREF TOP DTYPE>This very definition:
(dref 'dtype 'locative) ==> #<DREF DTYPE LOCATIVE>
-
- Direct locative supertypes: dtype
This is the locative for locative types defined with
define-locative-type,define-pseudo-locative-typeanddefine-locative-alias.(first-line (source-location-snippet (source-location (dref 'macro 'locative)))) => "(define-locative-type macro ()"
[locative] lambda &key arglist arglist-type docstring docstring-package file file-position snippet &allow-other-keys
A pseudo locative type that carries its
arglist,docstringandsource-locationin the locative itself. Seemake-source-locationfor the description offile,file-position, andsnippet.lambdareferences do notresolve. The name must benil.(arglist (dref nil '(lambda :arglist ((x y) z) :arglist-type :macro))) => ((X Y) Z) => :MACRO(docstring (dref nil '(lambda :docstring "xxx" :docstring-package :dref))) => "xxx" ==> #<PACKAGE "DREF">(source-location-file (source-location (dref nil '(lambda :file "xxx.el")))) => "xxx.el"Also, see the
pax:includelocative.
8 Extending DRef
8.1 Extension Tutorial
Let's see how to tell DRef about new kinds of definitions through
the example of the implementation of the class locative. Note that
this is a verbatim pax:include of the sources. Please
ignore any internal machinery. The first step is to define the
locative type:
(define-locative-type class (type)
"Naturally, CLASS is the locative type for [CLASS][class]es.
Also, see the related CONDITION locative.")
Then, we make it possible to look up class definitions:
(define-locator class ((class class))
(make-instance 'class-dref :name (class-name class) :locative 'class))
(define-lookup class (symbol locative-args)
(unless (and (symbolp symbol)
(find-class symbol nil))
(locate-error "~S does not name a class." symbol))
(make-instance 'class-dref :name symbol :locative 'class))
define-locator makes (locate (find-class 'dref)) work, while
define-lookup is for (dref 'dref 'class). Naturally, for locative
types that do not define first-class objects, the first method
cannot be defined.
Finally, we define a resolve* method to recover the class
object from a class-dref. We also specialize docstring* and
source-location*:
(defmethod resolve* ((dref class-dref))
(find-class (dref-name dref)))
(defmethod docstring* ((class class))
(documentation* class t))
(defmethod source-location* ((dref class-dref))
(swank-source-location* (resolve dref) (dref-name dref) 'class))
We took advantage of having just made the class locative type being
resolveable, by specializing docstring* on the class class.
source-location* was specialized on class-dref to demonstrate how
this can be done for non-resolveable locative types.
Classes have no arglist, so no arglist* method is needed. In the
following, we describe the pieces in detail.
8.2 Locative Type Hierarchy
Locative types form their own hierarchy, that
is only superficially similar to the Lisp class hierarchy.
The hierarchies of lisp-locative-types and pseudo-locative-types
are distinct. That is, the dref-class of a Lisp locative type must
not be a subclass of a pseudo one, and vice versa. This is enforced
by define-locative-type and define-pseudo-locative-type.
[function] dref-class locative-type
Return the name of the
classused to represent definitions withlocative-type. This is always a subclass ofdref. Returnsniliflocative-typeis not a valid locative type.Note that the actual
type-ofadrefis mostly intended for Extending DRef. Hence, it is hidden when adrefis printed:(dref 'print 'function) ==> #<DREF PRINT FUNCTION> (type-of *) => FUNCTION-DREFDue to Canonicalization, the actual type may be a proper subtype of
dref-class:(dref 'documentation 'function) ==> #<DREF DOCUMENTATION GENERIC-FUNCTION> (type-of *) => GENERIC-FUNCTION-DREF (subtypep 'generic-function-dref 'function-dref) => T => T
[function] locative-type-direct-supers locative-type
List the locative types whose
dref-classes are direct superclasses of thedref-classoflocative-type. These can be considered supertypes oflocative-typein the sense ofdtypep.This is ordered as in the corresponding definition.
[function] locative-type-direct-subs locative-type
List the locative types whose
dref-classes are direct subclasses of thedref-classoflocative-type. These can be considered subtypes oflocative-typein the sense ofdtypep.This list is in reverse definition order.
8.3 Defining Locative Types
[macro] define-locative-type locative-type-and-lambda-list locative-supertypes &optional docstring dref-defclass-form
Declare
locative-typeas alocative, which is the first step in Extending DRef.Simple example
To define a locative type called
dummythat takes no arguments and is not a locative subtype of any other locative type:(define-locative-type dummy () "Dummy docstring.")With this definition, only the locatives
dummyand its equivalent form(dummy)are valid. The above defines adref(01) subclass calleddummy-drefin the current package. All definitions with locative typedummyand its locatives subtypes must be instances ofdummy-dref.(locate 'dummy 'locative)refers to this definition. That is,arglist,docstringandsource-locationall work on it.Complex example
dummymay have argumentsxandyand inherit from locative typesl1andl2:(define-locative-type (dummy x &key y) (l1 l2) "Dummy docstring." (defclass dummy-dref () ((xxx :initform nil :accessor dummy-xxx))))One may change name of
dummy-dref, specify superclasses and add slots as withdefclass. Behind the scenes, thedrefclasses ofl1andl2are added automatically to the list of superclasses.
Arguments:
The general form of
locative-type-and-lambda-listis (locative-type&restlambda-list), wherelocative-typeis asymbol, andlambda-listis a destructuring lambda list. Thelocative-argsofdrefs with locative typelocative-type(the argument given to this macro) always conform to this lambda list. Seecheck-locative-args.If
locative-type-and-lambda-listis a single symbol, then that's interpreted aslocative-type, andlambda-listisnil.locative-supertypesis a list of locative types whosedref-classes are added to prepended to the list of superclasses this definition.
Locative types defined with
define-locative-typecan be listed withlisp-locative-types.
[macro] define-pseudo-locative-type locative-type-and-lambda-list locative-supertypes &optional docstring dref-defclass-form
Like
define-locative-type, but declare thatlocative-typedoes not correspond to definitions in the running Lisp. Definitions with pseudo locatives are ofdtypepseudoand are not listed by default bydefinitions.Locative types defined with
define-pseudo-locative-typecan be listed withpseudo-locative-types.
[macro] define-locative-alias alias locative-type &body docstring
Define
aliasthat can be substituted forlocative-type(bothsymbols) for the purposes oflocateing.locative-typemust exist (i.e. be amonglocative-types). For example, let's defineobjectas an alias of theclasslocative:(define-locative-alias object class)Then,
locateing withobjectwill find theclass:(dref 'xref 'object) ==> #<DREF XREF CLASS>The
locative-argsofobject(none in the above) are passed on toclass.(arglist (dref 'object 'locative)) => (&REST ARGS) => :DESTRUCTURINGNote that
locative-aliasesare notlocative-typesand are not validdtypes.Also, see Locative Aliases in PAX.
8.3.1 Symbol Locatives
Let's see how the opaque define-symbol-locative-type and the
obscure define-definer-for-symbol-locative-type macros work together
to simplify the common task of associating definition with a symbol
in a certain context.
[macro] define-symbol-locative-type locative-type-and-lambda-list locative-supertypes &optional docstring dref-class-def
Similar to
define-locative-type, but it assumes that all thingslocateable withlocative-typeare going to be symbols defined with a definer defined withdefine-definer-for-symbol-locative-type. Symbol locatives are for attaching a definition (along with arglist, documentation and source location) to a symbol in a particular context. An example will make everything clear:(define-symbol-locative-type direction () "A direction is a symbol.") (define-definer-for-symbol-locative-type define-direction direction "With DEFINE-DIRECTION, one can document what a symbol means when interpreted as a DIRECTION.") (define-direction up () "UP is equivalent to a coordinate delta of (0, -1).")After all this,
(dref 'up 'direction)refers to thedefine-directionform above.The
dref-classof the defined locative type inherits fromsymbol-locative-dref, which may be used for specializing when implementing new operations.
[macro] define-definer-for-symbol-locative-type name locative-type &body docstring
Define a macro with
namethat can be used to attach a lambda list, documentation, and source location to a symbol in the context oflocative-type. The defined macro's arglist is(symbol lambda-list &optional docstring).locative-typeis assumed to have been defined withdefine-symbol-locative-type.
8.4 Extending locate
Internally, locate finds an initial dref of its object
argument with a lookup or with a
locator. This initial dref is then canonicalized
with a series of casts. In more detail, the process
is as follows.
- If the
objectargument oflocateis adref, then it is returned without processing.
Else, locate first needs to finds the initial definition.
8.4.1 Initial Definition
locate can find the initial definition in one of two ways:
With direct lookup
If
objectis anxref(01), then the lookup for (xref-locative-typeobject) is invoked. For anxrefwith the locative(method (number)), this would be the lookup defined as(define-lookup method (name locative-args) ...)With locator search
Else,
objectis a normal Lisp object, such as amethodobject fromfind-method. The first oflisp-locative-typeswhose locator succeeds provides the initial definition, which may be defined like this:(define-locator method ((obj method)) ...)This is a locator that returns definitions with the
methodlocative type and takes an argument namedobjof classmethod(which is like a specializer indefmethod).lisp-locative-typesare tried one by one in the order specified there.For a given locative type, if there are multiple locators, standard CLOS method selection applies.
8.4.2 Canonicalization
The initial definition thus found is then canonicalized so that
there is a unique definition under xref=:
(locate #'arglist*)
==> #<DREF ARGLIST* GENERIC-FUNCTION>
(dref 'arglist* 'function)
==> #<DREF ARGLIST* GENERIC-FUNCTION>
(dref 'arglist* 'generic-function)
==> #<DREF ARGLIST* GENERIC-FUNCTION>
Canonicalization is performed by recursively attempting to
downcast the current definition to one of its
locative-type-direct-subs in a depth-first manner, backtracking if a
cast fails.
Default Downcast
Downcasting to direct locative subtypes is performed by default by looking up the definition where the locative type is replaced with its sub while the name and the locative args remain the same.
Cast Name Change
Casts must be careful about changing dref-name.
Their dref argument and the dref returned must have the
same dref-name (under equal, see xref=) or it must be possible to
upcast the returned value to the dref argument's dref-locative-type.
Implementation note
The purpose of this rule is to allow
dtypepanswer this correctly:(defclass foo () ((a :accessor foo-a))) (dref '(setf foo-a) '(method (t foo))) ==> #<DREF FOO-A (ACCESSOR FOO)> (dtypep * '(method (t foo))) => T ;; Internally, DTYPEP upcast #<DREF FOO-A (ACCESSOR FOO)> ;; and checks that the locative args of the resulting ;; definition match those in (METHOD (T FOO)). (locate* ** 'method) ==> #<DREF (SETF FOO-A) (METHOD (T FOO))>For even more background, also note that if the name remains the same but locative args change, then
dtypepcan simply check withdrefif there is a definition of the name with the given locative:(defclass foo () ((r :reader foo-r))) (dref 'foo-r '(reader foo)) ==> #<DREF FOO-R (READER FOO)> (dtypep * '(method (foo))) => T ;; Behind the scenes, DTYPEP does this: (xref= ** (dref 'foo-r '(method (foo)))) => T
8.4.3 Defining Lookups, Locators and Casts
As we have seen, the Initial Definition is provided either by a lookup or a locator, then Canonicalization works with casts. Here, we look at how to define these.
Implementation note: All three are currently implemented as
methods of generic functions with eql specializers for
the locative type, which may easily prove to be problematic down the
road. To make future changes easier, the generic function and the
methods are hidden behind e.g. the define-lookup and call-lookup
macros.
-
Enable runtime verification of invariants during
locatecalls. This carries a performance penalty and is intended for testing and debugging.In particular, enforce the rule of Cast Name Change and that lookups, locators and casts obey the following:
The value returned must be either
nilor adref(01). Alternatively,locate-error(01) may be signalled.If a
drefis returned, then itsdref-locative-typemust belocative-type, and its class must be thedref-classoflocative-type.locative-argsmust be congruent with the destructuring lambda list in the definition oflocative-type.
[macro] define-lookup locative-type (name locative-args) &body body
Define a method of looking up definitions of
locative-typewith the givenlocative-args. Lookups are invoked bylocatewhen itsobjectargument is anxref(01) withlocative-typebut it is not adref(01), as in the case of(dref 'print 'function). When called, the variablesnameandlocative-argsare bound toxref-nameandxref-locative-argsof thexref.locative-argsis validated withcheck-locative-argsbeforebodyis evaluated.(define-lookup variable (name locative-args) (unless (special-variable-name-p name) (locate-error)) (make-instance 'variable-dref :name name :locative 'variable))locative-typeis a valid locative type.nameandlocative-argsare bothsymbols.
The above are enforced at macro-expansion time.
bodymust follow the rules in*check-locate*.
[macro] call-lookup name locative-type locative-args
Call the lookup for
locative-typewithnameandlocative-args.
[macro] define-locator locative-type ((object class)) &body body
Define a method of finding the definition with
locative-typeof instances ofclass. When a locator'sbodyis evaluated,objectis bound to such an instance.(define-locator class ((class class)) (make-instance 'class-dref :name (class-name class) :locative 'class))locative-typeis one oflisp-locative-types. This is becausepseudo-locative-typesneverresolveto first-class objects.objectis asymbol.classnames aclassthat is not a subtype ofxref. For how to convert definitions from one locative type to another, seedefine-cast.
The above are enforced at macro-expansion time.
bodymust follow the rules in*check-locate*.
In contrast to when the Initial Definition is created from an
xref(seedefine-lookup), herelocative-argsare determined fromobject.
[macro] call-locator object locative-type
Call the locator for
locative-typewithobject.
[macro] define-cast locative-type ((dref dref-class)) &body body
Define a method of converting a definition to another with
locative-type. When a cast'sbodyis evaluated,drefis bound to an instancedref-class, which denotes a valid but potentially non-canonical definition.Note the Default Downcast often suffices, and defining a cast is only necessary if the name or the locative args change:
(define-cast accessor ((dref reader-dref)) (let ((name (dref-name dref)) (class (second (dref-locative dref)))) (when (ignore-errors (find-accessor-slot-definition name class)) (make-instance 'accessor-dref :name name :locative `(accessor ,class)))))locative-typeis a valid locative type.If
locative-typeis one ofpseudo-locative-types, thendref-classmust be of another pseudo locative type.dref-classis either a direct downcast or an potentially non-direct upcast.Downcast: In this case,
locative-typeis one oflocative-type-direct-subsof (dref-class-to-locative-typedref-class).Downcasting to non-direct subtypes is done in multiple steps. Consequently,the
bodyof a downcast can rely on (class-ofdref) beingclass, not any subclass thereof.Upcast:
locative-typeis different but reachable from (dref-class-to-locative-typedref-class) by repeatedly choosing one oflocative-type-direct-supers. Upcasting to non-direct supertypes is done in one step.
The above are enforced at macro-expansion time.
bodymust follow the rules in*check-locate*, including those in Cast Name Change.
[function] locate-error &optional format-control &rest format-args
Call this function to signal a
locate-errorcondition from the dynamic extent of alocatecall, that is, from thebodys ofdefine-lookup,define-locatoranddefine-cast. It is an error to calllocate-errorelsewhere.format-control, if non-nil, is a format control for whichformat-argsare suitable.
[macro] check-locative-args locative-type locative-args
Signal a
locate-errorcondition iflocative-argsdo not match thelambda-listargument oflocative-type(not evaluated).
8.5 Extending Everything Else
[generic-function] resolve* dref
Return the object defined by the definition
drefrefers to. Signal aresolve-errorcondition by calling theresolve-errorfunction if the lookup fails.To keep
resolvea partial inverse oflocate,define-locatormay be necessary forresolveable definitions. This function is for extendingresolve. Do not call it directly.It is an error for methods of this generic function to return an
xref.
[function] resolve-error &rest format-and-args
Call this function to signal a
resolve-errorcondition from the dynamic extent of aresolve*method. It is an error to callresolve-errorelsewhere.format-and-args, if non-nil, is a format string and arguments suitable forformat.
[generic-function] map-definitions-of-name fn name locative-type
Call
fnwithdrefs which can belocated with anxref(01) withname,locative-typeand somelocative-args. The strange wording here is because there may be multiple ways (and thusxrefs) that refer to the same definition.For most locative types, there is at most one such definition, but for
method, for example, there may be many. The default method simply does(dref name locative-type nil)and callsfnwith result ifdrefsucceeds.fnmust not be called with the same (underxref=) definition multiple times.This function is for extending
definitionsanddref-apropos. Do not call it directly.
[generic-function] map-definitions-of-type fn locative-type
Call
fnwithdrefs which can belocated with anxref(01) withlocative-typewith somenameandlocative-args.The default method forms
xrefs by combining each interned symbol as names withlocative-typeand nolocative-argsand callsfnif itlocates a definition.fnmay be called withdrefs that arexref=but differ in thexrefin theirdref-origin.This function is for extending
dref-apropos. Do not call it directly.
[generic-function] arglist* object
To extend
arglist, specializeobjecton a normal Lisp type or on a subclass ofdref.arglistfirst callsarglist*with itsobjectargument. If that doesn't work (i.e. the second value returned isnil), then it callsarglist*withobjecteitherresolved (if it's adref) orlocated (if it's not adref).The default method returns
nil,nil.There is also a method specialized on
drefs, that looks up thedefinition-propertycalledarglistand returns its value withvalues-list. Thus, an arglist and its kind can be specified with something like(setf (definition-property xref 'arglist) (list arglist :destructuring))
This function is for extension only. Do not call it directly.
[generic-function] docstring* object
To extend
docstring, specializeobjecton a normal Lisp type or on a subclass ofdref.docstringfirst callsdocstring*with itsobjectargument. If that doesn't work (i.e.nilis returned), then it callsdocstring*withobjecteitherresolved (if it's adref) orlocated (if it's not adref).The default method returns
nil.There is also a method specialized on
drefs, that looks up thedefinition-propertycalleddocstringand returns its value withvalues-list. Thus, a docstring and a package can be specified with something like(setf (definition-property xref 'docstring) (list docstring *package*))
This function is for extension only. Do not call it directly.
[generic-function] source-location* object
To extend
source-location, specializeobjecton a normal Lisp type or on a subclass ofdref.source-locationfirst callssource-location*with itsobjectargument. If that doesn't work (i.e.nilor(:error <message>)is returned), then it callssource-location*withobjecteitherresolved (if it's adref) orlocated (if it's not adref).source-locationreturns the last of the(:error <message>)s encountered or a generic error message if onlynils were returned.The default method returns
nil.There is also a method specialized on
drefs, that looks up thedefinition-propertycalledsource-location. If present, it must be a function of no arguments that returns a source location ornil. Typically, this is set up in the defining macro like this:(setf (definition-property xref 'source-location) (this-source-location))
This function is for extension only. Do not call it directly.
8.5.1 Definition Properties
Arbitrary data may be associated with definitions.
This mechanism is used by arglist*, docstring* and
source-location* for easy extension.
The following functions take an xref argument and not a dref(0 1) to
allow working with non-canonical or
non-existent definitions.
[function] definition-property xref indicator
Return the value of the property associated with
xrefwhose name iseql(01) toindicator. The second return value indicates whether the property was found.setfable.
[function] delete-definition-property xref indicator
Delete the property associated with
xrefwhose name iseql(01) toindicator. Return true if the property was found.
[function] definition-properties xref
Return the properties of
xrefas an association list.
[function] delete-definition-properties xref
Delete all properties associated with
xref.
[function] move-definition-properties from-xref to-xref
Associate all properties of
from-xrefwithto-xref, as if readding them one-by-one with(setf definition-property), and deleting them fromfrom-xrefwithdelete-definition-property.
8.6 dref-classes
These are the dref-classes corresponding to Basic Locative Types.
They are exported to make it possible to go beyond the
Basic Operations (e.g. pax:document-object*). For
Defining Locative Types, they are not necessary, as
define-locative-type handles inheritance automatically based on its
locative-supertypes argument.
[class] symbol-locative-dref dref
All locative types defined with
define-symbol-locative-typeinherit from this class.
8.7 Source Locations
These represent the file or buffer position of a defining
form and are returned by the source-location function. For
the details, see the Elisp function slime-goto-source-location.
[function] make-source-location &key file file-position buffer buffer-position snippet
Make a Swank source location. The ultimate reference is
slime.el. Whensnippetis provided, the match nearest tofile-positionis determined (see the Elispslime-isearchandsource-location-adjusted-file-position).
[function] source-location-p object
See if
objectis a source location object.
[function] source-location-file location
Return the name of the file of the defining form. This may be
nil, for example, iflocationis of a defining form that was entered at the REPL, or compiled in the*slime-scratch*buffer.
[function] source-location-file-position location
Return the file position of the defining form or
nilif it's not available. The first position is 0.
[function] source-location-buffer location
Return the name of the Emacs buffer of the defining form or
nilif there is no such Emacs buffer.
[function] source-location-buffer-position location
Return the position of the defining form in
source-location-bufferornilif it's not available. The first position is 1.
[function] source-location-snippet location
Return the defining form or a prefix of it as a string or
nilif it's not available.
[function] source-location-adjusted-file-position location
Return the actual file position
locationpoints to allowing for some deviation from the rawsource-location-file-position, which is adjusted by searching for the nearest occurrence ofsource-location-snippetin the file. Needless to say, this can be a very expensive operation.If
source-location-fileisnil,nilis returned. If there is no snippet, or it doesn't match, thensource-location-file-position(or 0 if that'snil) is returned.This is a non-interactive companion to the Elisp function
slime-location-offset, supporting only file positions and non-partial matching of snippets.
-
The value of this macro form is a function of no arguments that returns its own
source-location.