Definitions are implemented as an object-oriented hierarchy rooted in
the definition
class. The complete description of this hierarchy
is provided in the Declt
Reference Manual.
This section provides an overview of the hierarchy in question, along
with the most important remarks about it. Every definition class in the
hierarchy has a name of the form foo-definition
. For concision,
and except for the definition
and mixin classes, all class names
in the figures below are abbreviated: a foo-definition
class is
simply denoted as foo
. Abstract classes are drawn in red boxes
with bold text, regular classes in blue boxes with normal font, and
mixins (also abstract) in green ellipses with bold text.
Figure 6.1: Main definition categories
As depicted in Figure 6.1, there are three main categories of
definitions: component-definition
is the root class for ASDF
components, package-definition
is the class for Lisp packages,
and symbol-definition
is the root class of all programmatic
definitions named by symbols. The definition
root class provides
common properties, such as a reference to the corresponding Lisp object
(when applicable), source information, and foreign status.
Figure 6.2: ASDF component definitions
Figure 6.2 depicts the hierarchy of ASDF definitions. Unsurprisingly, this hierarchy closely follows that of actual ASDF components, although some peculiarities are worth mentioning here.
lisp-file-definition
class corresponds to the ASDF
cl-source-file
one. Note that ASDF provides two additional
subclasses for Lisp files, with extensions ‘.cl’ and ‘.lsp’.
We don’t do that, however. Instead, there is a protocol for retrieving a
file component’s extension.
system-file-definition
class, which is
a subclass of lisp-file-definition
. In ASDF, system files are
not represented as components, but Declt
pretends they are by
faking a particular class of Lisp files for them. This allows us to
document .asd
files as particular Lisp files, without too much
specific code. Note also that some (few) libraries list their system
files (for example as static files) in the system definition. Declt
is aware of this and removes such definitions, so as to avoid
duplication.
The hierarchy of definitions named by symbols (under the
symbol-definition
class) is quite large, so it is split into four
figures.
Figure 6.3: Varoid definitions
The varoid ones (Figure 6.3) represent simple values having symbolic names. This boils down to variables, symbol macros, and slots.
Figure 6.4: Funcoid definitions
The funcoid ones (Figure 6.4) covers “parametric
values”, that is, values having a lambda-list of some sort. This
includes all variations on functions, macros, methods, types, setf
expanders, and method combinations. You may wonder why the
combination-definition
class is not abstract. That is because the
standard method combination is an instance of it. All funcoids have a
slot indicating whether the definition is a setf one (e.g. a function
named (setf foo)
). The “setfable” branch represents definitions
that may be related to a setf expander (that is, which could be either
an access-fn or an update-fn). As a matter of fact, this
hierarchy is not 100% correct: some funcoids can never be setf ones, and
some setfable ones can never be related to a setf expander. On the other
hand, doing it like this keeps said hierarchy relatively simple.
The “accessor” sub-branches represent definitions for methods, ordinary, or generic functions, which have been identified as reading or writing slots. The accessor mixin provides a back reference to the slot definition in question. Note that generic functions do not access slots; only their methods do (which is why the generic accessor branch does not use the accessor mixin). A generic function will be qualified as a generic reader (respectively a generic writer) if all its methods have been identified as reader (respectively writer) methods.
Figure 6.5: Classoid definitions
The classoid branch (Figure 6.5) represents (typed)
structures, classes, and conditions. This part of the definitions
hierarchy is probably not portable, as it relies on how SBCL implements
a number of things, in particular, which classoids are in fact CLOS
classes, which is represented by the CLOS classoid mixin. The CLOS
classoid mixin provides super- and sub-classoid information, but this
may change in the future. Indeed, it is perhaps possible to trace back
:include
information for typed structures as well, but this is
not currently implemented.
Figure 6.6: Alias definitions
Finally, the last group of symbol definitions is for aliases, that
is, globally defined (compiler) macros or functions that are also
manually attached to other symbols. Aliases are known to Declt
so as
to avoid duplicating documentation.