该函数返回定义 symbol(符号)的文件名。
若 type 为 nil,则接受任意类型的定义;
若 type 为 defun、defvar 或 defface,则仅分别匹配函数定义、变量定义或面孔(face)定义。
返回值通常为绝对文件名;若该定义未关联任何文件,返回值可为 nil;
若 symbol 指向一个自动加载函数,返回值可为无扩展名的相对文件名。
如果可选的第三个参数 native-p 为非 nil 值,且 Emacs 编译时启用了原生编译支持(see Lisp 本地代码编译),
该函数会尝试查找定义 symbol 的 .eln 文件,而非 .elc 或 .el 文件。
若找到对应的 .eln 文件且该文件未过期,则返回其绝对文件名;否则返回源码文件或字节编译文件的名称。
symbol-file 的实现基于变量 load-history 中的数据。
该变量的值是一个关联列表(alist),将已加载库文件的名称与它们定义的函数、变量,以及提供或需求的功能(feature)关联起来。
该关联列表中的每个元素描述一个已加载的库(包括启动时预加载的库),其结构为一个列表: CAR 部分是库的绝对文件名(字符串),其余元素的格式如下:
var符号 var 被定义为变量。
(defun . fun)函数 fun 被定义。((defun . fun) 该形式表示将 fun 定义为函数)。
(defface . face)面孔 face 被定义。
(require . feature)功能 feature 被需求(require)。
(provide . feature)功能 feature 被提供(provide)。
(cl-defmethod method specializers)通过 cl-defmethod 定义了名为 method 的方法,specializers 为其特殊化参数。
(define-type . type)类型 type 被定义。
load-history 的值中可能包含一个 CAR 为 nil 的元素,该元素描述通过 eval-buffer 在未关联文件的缓冲区中完成的定义。
命令 eval-region 会更新 load-history,但更新方式是将定义的符号添加到当前访问文件对应的元素中,而非替换该元素。See 求值。
除 load-history 外,每个函数还会在其符号属性 function-history 中记录自身的历史。
函数在此处被特殊处理的原因是:函数通常会分两步在两个不同文件中定义(其中一个通常是自动加载文件),
因此为了能够正确地 卸载(unload) 文件,需要更精确地知晓该文件对函数定义所做的修改。
符号属性 function-history 保存一个格式为 (file1 def2 file2 def3 ...) 的列表:
其中 file1 是最后修改该函数定义的文件,def2 是 file1 修改前的定义(由 file2 设置),依此类推。
逻辑上该列表应终止于首次定义该函数的文件名,但为节省空间,这最后一个元素通常会被省略。