语言服务信息
公开「元类型」
软件架构说明
本文件是编译器与编辑器扩展之间的语言服务资料层。它不直接响应编辑器请求,
而是在正常编译过程中收集名称与类型资料,再将资料写入构建缓存。编辑器扩展
收到悬停或跳转请求时,只需读取最近一次编译留下的语言服务癸象文件,因此编译器
本身无需常驻,也不需要另设通信进程。
一、整体资料流
一.分布编译步骤在读取某个源文件的抽象语法后,调用「准备语言服务信息」。
此操作读取原始源码,并清空本文件中属于上一文件的收集状态。
二.名称解析负责确定每个名称究竟引用哪个局部绑定、文件定义或构造器。
名称一旦解析成功,便调用「标注引用语言服务信息」:一方面记录“引用范围到
定义范围”的关系,另一方面把原表达式包在「源码范围标注节点」中。跳转到定义
因而在名称解析这个拥有最准确信息的阶段完成,不依赖之后的类型推断结果。
三.类型检查遇到「源码范围标注节点」时,先照常求得被标注表达式的类型,再调用
「悬停类型文字」与「记录悬停文字信息」,最后只返回检查后的原表达式。
标注节点是名称解析与类型检查之间的暂存节点,绝不能流入擦除、优化或代码生成。
顶层定义和构造器没有普通引用节点包裹,所以文件结构检查会另外调用
「记录定义悬停」,为定义处补上悬停资料。
四.类型检查结束后,分布编译步骤调用「写语言服务信息」,把本文件收集的资料
与源文件、检查后定义等产物放在同一个构建缓存目录。编辑器扩展从最新缓存中
找到对应源文件的“语言服务”产物,按请求筛选覆盖光标且范围最窄的一项。
二、本文件内部的分层
资料模型层由「语言服务信息」与「源码范围」组成。目前只有两种资料:
「定义位置信息」保存引用范围及目标范围;「悬停文字信息」保存范围及显示文字。
源码定位层由「源码搜索状态」及一组“寻找源码……”函数组成。抽象语法树目前
不永久保存词法位置,因此本层从原始源码中重建名称范围。搜索器会跳过字符串和
可嵌套注释,并使用单调向前的游标,使名称解析遍历与源码遍历大体保持线性。
引用搜索与声明搜索各有独立游标,避免寻找声明时消耗引用位置。跨文件定义范围
则存入「定义范围缓存」,防止同一外部定义被反复读取和扫描。
显示层由「内建常量悬停表示」「悬停类型表示」和「悬停类型文字」组成。这里使用
面向使用者的中文类型表示,不调用抽象语法树的调试表示器,避免把内部节点名称、
缓存路径和调试符号泄漏到悬停内容。
收集层以「当前语言服务文件」「当前语言服务信息」及两个搜索状态引用保存一次
文件编译期间的临时状态。并行编译以独立进程处理文件,所以这些进程内引用不会
在不同源文件之间共享;即便如此,每次处理文件仍必须先调用准备函数完成重置。
序列化层把内部资料转换为癸象对象。对外协议只使用中文字段与中文种类值:根对象
包含“版本、源文件、信息”;范围包含“文件、开始行、开始列、结束行、结束列”;
资料种类为“定义”或“悬停”。编辑器扩展会严格检查这些字段,旧协议不会复用。
三、必须保持的约定
所有行列均从零开始,范围采用左闭右开的半开区间。文件路径用于唯一标识源文件,
定义目标可以位于另一文件。收集时使用前衔写入以降低逐项追加成本,序列化前必须
反转,才能恢复源码顺序。若增加新的语言服务资料种类,必须同时更新本文件的资料
模型与序列化分支,以及编辑器扩展的解析和请求处理。若改变名称解析或类型检查中
对标注节点的处理,也必须确认标注节点在类型检查结束时已被完全移除。
定义位置信息
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「语言服务信息」
暂无说明。
悬停文字信息
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化「字符串」而「语言服务信息」
暂无说明。
源码搜索状态
公开「元类型」
暂无说明。
当前语言服务文件
公开(「引用类」于「字符串」)
剩余字符、当前行、当前列。
当前语言服务信息
公开(「引用类」于(「列」于「语言服务信息」))
暂无说明。
当前名称搜索状态
公开(「引用类」于((「列」于「字符串」)合「整数」合「整数」))
暂无说明。
当前定义搜索状态
公开(「引用类」于((「列」于「字符串」)合「整数」合「整数」))
暂无说明。
定义范围缓存
公开(「引用类」于(「串典」于(「字符串」合「整数」合「整数」合「整数」合「整数」)))
暂无说明。
当前悬停范围缓存
公开(「引用类」于(「串典」于「有」))
暂无说明。
构造源码范围
公开化「字符串」而化「整数」而化「整数」而化「整数」而化「整数」而(「字符串」合「整数」合「整数」合「整数」合「整数」)
暂无说明。
源码范围文件
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「字符串」
暂无说明。
源码范围开始行
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「整数」
暂无说明。
源码范围开始列
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「整数」
暂无说明。
源码范围结束行
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「整数」
暂无说明。
源码范围结束列
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「整数」
暂无说明。
悬停范围缓存键
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「字符串」
暂无说明。
语言服务信息范围
公开化「语言服务信息」而(「字符串」合「整数」合「整数」合「整数」合「整数」)
暂无说明。
源码范围开始早于
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「爻」
暂无说明。
内建常量悬停表示
公开化「内建常量」而「字符串」
暂无说明。
悬停类型表示
公开化「表达式」而「字符串」
暂无说明。
悬停类型文字
公开化「表达式」而「字符串」
暂无说明。
源码状态剩余
公开化((「列」于「字符串」)合「整数」合「整数」)而(「列」于「字符串」)
暂无说明。
源码状态行
公开化((「列」于「字符串」)合「整数」合「整数」)而「整数」
暂无说明。
源码状态列
公开化((「列」于「字符串」)合「整数」合「整数」)而「整数」
暂无说明。
源码字符前缀匹配
公开化(「列」于「字符串」)而化(「列」于「字符串」)而「爻」
文言:字符相比无旁效,异则可止;通用列术之约不改。汉语:这里的比较固定为纯字符串相等,且两列有限;发现不等即可停止,避免继续遍历前缀。带用户比较函数的通用以起否仍保持原来的求值语义。
源码状态以串开头
公开化((「列」于「字符串」)合「整数」合「整数」)而化「字符串」而「爻」
暂无说明。
源码状态前进一字
公开化((「列」于「字符串」)合「整数」合「整数」)而((「列」于「字符串」)合「整数」合「整数」)
暂无说明。
源码状态前进
公开化((「列」于「字符串」)合「整数」合「整数」)而化「整数」而((「列」于「字符串」)合「整数」合「整数」)
暂无说明。
源码状态前进字符串
公开化((「列」于「字符串」)合「整数」合「整数」)而化「字符串」而((「列」于「字符串」)合「整数」合「整数」)
暂无说明。
源码状态是注释开头
公开化((「列」于「字符串」)合「整数」合「整数」)而「爻」
暂无说明。
源码状态是注释结尾
公开化((「列」于「字符串」)合「整数」合「整数」)而「爻」
暂无说明。
跳过源码注释
公开化((「列」于「字符串」)合「整数」合「整数」)而化「整数」而((「列」于「字符串」)合「整数」合「整数」)
暂无说明。
跳过源码字符串
公开化((「列」于「字符串」)合「整数」合「整数」)而((「列」于「字符串」)合「整数」合「整数」)
暂无说明。
读取源码引号名称
公开化「字符串」而化((「列」于「字符串」)合「整数」合「整数」)而化(「列」于「字符串」)而化「整数」而化「整数」而(「或可有」于(「字符串」合(「字符串」合「整数」合「整数」合「整数」合「整数」)合((「列」于「字符串」)合「整数」合「整数」)))
暂无说明。
声明后缀
公开化((「列」于「字符串」)合「整数」合「整数」)而「爻」
暂无说明。
寻找源码名称范围
公开化「字符串」而化「字符串」而化((「列」于「字符串」)合「整数」合「整数」)而(「或可有」于((「字符串」合「整数」合「整数」合「整数」合「整数」)合((「列」于「字符串」)合「整数」合「整数」)))
暂无说明。
寻找源码绑定范围
公开化「字符串」而化「字符串」而化((「列」于「字符串」)合「整数」合「整数」)而(「或可有」于((「字符串」合「整数」合「整数」合「整数」合「整数」)合((「列」于「字符串」)合「整数」合「整数」)))
暂无说明。
寻找源码声明范围
公开化「字符串」而化「字符串」而化((「列」于「字符串」)合「整数」合「整数」)而(「或可有」于((「字符串」合「整数」合「整数」合「整数」合「整数」)合((「列」于「字符串」)合「整数」合「整数」)))
暂无说明。
是阿拉伯数字
公开化「字符串」而「爻」
暂无说明。
去除名称末尾序数
公开化「字符串」而「字符串」
暂无说明。
定义范围缓存键
公开化「字符串」而化「字符串」而「字符串」
暂无说明。
准备语言服务信息
公开化「字符串」而「有」
暂无说明。
查找下个名称源码范围
公开化「字符串」而(「或可有」于(「字符串」合(「字符串」合「整数」合「整数」合「整数」合「整数」)))
暂无说明。
查找下个绑定源码范围
公开化「字符串」而(「或可有」于(「字符串」合(「字符串」合「整数」合「整数」合「整数」合「整数」)))
暂无说明。
查找并记录当前定义范围
公开化「字符串」而(「或可有」于(「字符串」合「整数」合「整数」合「整数」合「整数」))
暂无说明。
查找文件定义范围
公开化「字符串」而化「字符串」而(「或可有」于(「字符串」合「整数」合「整数」合「整数」合「整数」))
暂无说明。
记录定义位置信息
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「有」
暂无说明。
记录悬停文字信息
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化「字符串」而「有」
暂无说明。
表达式定义范围
公开化「表达式」而(「或可有」于(「字符串」合「整数」合「整数」合「整数」合「整数」))
暂无说明。
标注引用语言服务信息
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而化「表达式」而「表达式」
暂无说明。
记录定义悬停
公开化「字符串」而化「字符串」而化「表达式」而「有」
暂无说明。
源码范围转癸象
公开化(「字符串」合「整数」合「整数」合「整数」合「整数」)而「癸象」
暂无说明。
语言服务信息转癸象
公开化「语言服务信息」而「癸象」
暂无说明。
写语言服务信息
公开化「字符串」而「有」
暂无说明。
语言服务阶段快照
公开化「有」而(「列」于(「字符串」合「爻」合「表达式」))
文言:名解所记,存而复之,毋失跳转。汉语:名称解析与类型检查分进程后,仍保留名称解析收集的定义位置资料。
恢复语言服务阶段快照
公开化(「列」于(「字符串」合「爻」合「表达式」))而「有」
暂无说明。