全文5000字,解读 vscode 背后的代码高亮实现原理,欢迎点赞关注转发。
Vscode 的代码高亮、代码补齐、错误诊断、跳转定义等语言功能由两种扩展方案协同实现,包括:
- 基于词法分析技术,识别分词 token 并应用高亮样式
- 基于可编程语言特性接口,识别代码语义并应用高亮样式,此外还能实现错误诊断、智能提示、格式化等功能
【推荐学习:《vscode教程》】
两种方案的功能范畴逐级递增,相应地技术复杂度与实现成本也逐级升高,本文将概要介绍两种方案的工作过程与特点,各自完成什么工作,互相这么写作,并结合实际案例一步步揭开 vscode 代码高亮功能的实现原理:
Vscode 插件基础
介绍 vscode 代码高亮原理之前,有必要先熟悉一下 vscode 的底层架构。与 Webpack 相似,vscode 本身只是实现了一套架子,架子内部的命令、样式、状态、调试等功能都以插件形式提供,vscode 对外提供了五种拓展能力:
其中,代码高亮功能由 语言扩展 类插件实现,根据实现方式又可以细分为:
- 声明式 :以特定 JSON 结构声明一堆匹配词法的正则,无需编写逻辑代码即可添加如块级匹配、自动缩进、语法高亮等语言特性,vscode 内置的 extendsions/css、extendsions/html 等插件都是基于声明式接口实现的
- 编程式 :vscode 运行过程中会监听用户行为,在特定行为发生后触发事件回调,编程式语言扩展需要监听这些事件,动态分析文本内容并按特定格式返回代码信息
声明式性能高,能力弱;编程式性能低,能力强。语言插件开发者通常可以混用,用声明式接口在最短时间内识别出词法 token,提供基本的语法高亮功能;之后用编程式接口动态分析内容,提供更高级特性比如错误诊断、智能提示等。
Vscode 中的声明式语言扩展基于 TextMate 词法分析引擎实现;编程式语言扩展则基于语义分析接口、vscode.language.*
接口、Language Server Protocol 协议三种方式实现,下面展开介绍每种技术方案的基本逻辑。
词法高亮
词法分析(Lexical Analysis) 是计算机学科中将字符序列转换为 标记(token) 序列的过程,而 标记(token) 是构成源代码的最小单位,词法分析技术在编译、IDE等领域有非常广泛的应用。
比如 vscode 的词法引擎分析出 token 序列后再根据 token 的类型应用高亮样式,这个过程可以简单划分为分词、样式应用两个步骤。
参考资料:
- https://macromates.com/manual/en/language%5C_grammars
https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide
分词
分词过程本质上将一长串代码递归地拆解为具有特定含义、分类的字符串片段,比如 +-*/%
等操作符;var/const
等关键字;1234
或 "tecvan"
类型的常量值等,简单说就是从一段文本中识别出,什么地方有一个什么词。