ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Gleam v1.10.0 版本发布全解析:编译器诊断增强、语言服务器新特性与构建工具升级

Gleam v1.10.0 版本发布全解析:编译器诊断增强、语言服务器新特性与构建工具升级 Gleam v1.10.0 版本发布全解析编译器诊断增强、语言服务器新特性与构建工具升级【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam导读本文基于 Gleam 官方变更日志 changelog/v1.10.md 撰写系统梳理 v1.10.0 与 v1.10.0-rc1 两个版本的核心更新涵盖编译器不可达分支检测、调用图驱动的未使用告警、位数组增强、类型错误信息优化、JavaScript 代码生成改进、构建工具gleam export新选项、erlang-shipment 双入口脚本、Hex 认证方式调整、语言服务器跨模块重命名、查找引用、十余项新 code action以及容器镜像供应链安全等多个方面。读完本文你将完整掌握 v1.10 的变更全貌并理解这些功能在仓库源码中的落地实现。版本时间线与发布节奏v1.10 的发布遵循 Gleam 一贯的先出候选版、再出正式版节奏版本发布日期定位v1.10.0-rc12025-04-05候选版包含全部新特性与大部分 Bug 修复v1.10.02025-04-14正式版在 rc1 基础上追加了 2 项 Bug 修复正式版相对候选版追加的修复包括unqualify 类型/值的 code action 在已有导入的情况下会重复添加无限定导入的问题以0x_、0o_、0b_开头的数字在编译到 JavaScript 时会触发语法错误的问题。下文先详述正式版修复再按模块展开候选版引入的完整特性清单。编译器更智能的诊断与更稳的代码生成不可达 case 分支现在会被警告编译器现在能够判断字符串分支是否不可达。以下代码中Hello, name这个前缀匹配分支已经覆盖了以Hello, 开头的所有字符串因此紧随其后的Hello, Jak分支永远不会被命中case a_string { Hello, name - name Hello, Jak - Jak _ - Stranger }编译时会得到如下警告warning: Unreachable case clause ┌─ /src/greet.gleam:7:5 │ 7 │ Hello, Jak - Jak │ ^^^^^^^^^^^^^^^^^^^^^ This case clause cannot be reached as a previous clause matches the same values. Hint: It can be safely removed.这项能力在源码层面由 compiler-core/src/exhaustiveness.rs 的穷举性/可达性分析支撑——该模块负责模式匹配的覆盖度检查v1.10 将字符串前缀拼接的匹配关系纳入分析从而推导出前一条分支已匹配同样值的结论。调用图驱动的未使用检测覆盖递归函数v1.10 编译器改用调用图call graph来检测未使用的类型和值。这意味着此前难以判定的自递归但从未被外部调用的函数现在也能被准确识别// warning: unused fn some_recursive_function() { some_recursive_function() }在仓库中调用图的构建实现在 compiler-core/src/call_graph.rs该模块使用 petgraph 的有向图将模块内的每个函数CallGraphNode::Function和常量CallGraphNode::ModuleConstant注册为图节点遍历函数体与常量值中的引用关系建立边再按依赖顺序分析可达性未被任何入口引用到的节点即判定为未使用。这也是 v1.10 对未使用代码这一经典告警的算法级升级。let assert恒定崩溃警告当使用let assert断言一个变体已被推断出来的值时编译器会提示该断言必然失败// warning: This will always crash let assert Ok(_) Error(Some error)因为Error(Some error)的变体在构造时已经确定是Error与Ok(_)模式必然不匹配运行时必然 panic编译器提前给出警告。位数组BitArray的三项增强JavaScript 目标支持unit选项此前unit仅在 Erlang 目标生效v1.10 起 JavaScript 目标下位数组的size选项可以配合unit使用来控制大小单位。16 位浮点支持JavaScript 目标下表达式和模式中的位数组可以使用 16-bit floats即半精度浮点。省略:float选项位数组段中的浮点字面量不再强制写:float以下两种写法完全等价1.11 1.11:float更友好的类型错误信息v1.10 针对选错运算符这一最常见的类型错误给出了带修正建议的提示用拼接字符串应改用error: Type mismatch ┌─ /src/wibble.gleam:2:13 │ 2 │ Hello, Lucy │ ^ Use instead The operator can only be used on Ints. To join two strings together you can use the operator.对 Float 使用 Int 运算符应改用.error: Type mismatch ┌─ /src/prova.gleam:2:7 │ 2 │ 1.0 2.0 │ ^ Use . instead The operator can only be used on Ints.对 Int 使用 Float 运算符应改用error: Type mismatch ┌─ /src/prova.gleam:2:5 │ 2 │ 1 . 2 │ ^^ Use instead The . operator can only be used on Floats.这些错误信息与语言服务器的自动修复 code action 配合见下文形成报错 一键修复的完整闭环。二元运算符容错编译二元运算符的编译现在是**容错fault tolerant**的即使表达式存在类型错误编译器也不会在第一个错误处停下而是继续分析并报告所有同类错误避免用户改一个错、再冒出一个错的反复编译。函数标签相关错误收敛当被调用的函数本身不存在时编译器不再就它的标签labels继续报错从而减少误导性的级联错误让真正的问题函数未定义一目了然。JavaScript 代码生成优化JavaScript 目标下块blocks及其他多种表达式不再编译为立即调用函数表达式IIFE。这既减少了生成代码的体积与嵌套层级也让编译产物更贴近手写 JavaScript 的可读风格便于调试与审查。target属性的错误信息改进对target属性中出现未知或缺失目标名的情况编译器提供了更清晰的错误提示帮助用户快速定位拼写错误或平台名不合法的问题。构建工具与发布流程更顺手的工程化体验gleam new生成带类型注解的main函数由gleam new脚手架生成的项目模板中main函数现在带上了显式类型注解pub fn main() - Nil使新项目的起步代码类型意图更明确也方便在生成后直接改造为带参数或返回值的入口。gleam export erlang-shipment始终生成双入口脚本gleam export erlang-shipment现在总是生成两个入口脚本entrypoint.sh—— POSIX Shell 版本entrypoint.ps1—— PowerShell 版本此前两种脚本的生成行为与平台相关v1.10 起统一为跨平台各生成一份方便用户在 Linux/macOS 与 Windows 上都能直接运行导出的 Erlang 发布包。实现上compiler-cli/src/export.rs 的erlang_shipment函数在复制完各包的ebin、priv、include目录后会调用write_entrypoint_script将模板中的$PACKAGE_NAME_FROM_GLEAM占位符替换为真实包名并写入输出目录见 compiler-cli/templates/erlang-shipment-entrypoint.sh 与 compiler-cli/templates/erlang-shipment-entrypoint.ps1。生成的entrypoint.sh支持两个子命令run调用PACKAGEmain:run(PACKAGE)运行项目 main 函数与shell进入 Erlang shell未带参数或参数不合法时打印用法帮助。这使得导出的发布目录可以直接拷到装有 Erlang 的服务器上执行无需任何构建工具链。gleam export新增package-information选项gleam export命令现在接受package-information选项用于把项目的gleam.toml以 JSON 形式导出。其实现对应 compiler-cli/src/export.rs 中的package_information函数读取根配置后调用docs::package_information_as_json(config)序列化为 JSON可输出到指定文件或标准输出。这一能力对 CI 流水线、发布脚本等需要程序化读取项目元数据的场景非常实用。Hex API key 的认证方式调整两个与 Hex 发布认证相关的变更HEXPM_USER与HEXPM_PASS环境变量弃用gleam publish时使用这两个变量进行认证的做法已被弃用统一改用HEXPM_API_KEY。在 compiler-cli/src/hex/auth.rs 中可以看到HEXPM_API_KEY写操作与HEXPM_READ_API_KEY只读操作两个环境变量常量定义本地存储的旧式 API key 会通过 OAuth 流程自动迁移新 OAuth 令牌以本地密码加密保存。本地 Hex API key 加解密失败的错误信息改进当本地保存的 API key 加密/解密失败时错误信息更明确方便用户判断是密钥损坏还是本地密码不匹配。HTML 文档结构优化生成的 HTML 文档中functions函数与 constants常量两个章节被合并为单一的 values值章节文档导航更简洁也减少了同一模块中函数与常量并列时的视觉割裂。语言服务器从提示到自动改v1.10 的语言服务器LSP迎来一次大版本级的功能扩充覆盖重命名、引用查找与十余个新 code action。相关实现分布在 language-server/src/rename.rs、language-server/src/reference.rs、language-server/src/code_action.rs 等模块中。跨模块重命名现在可以对函数、常量、自定义类型变体、自定义类型执行跨模块重命名。例如将wibble.gleam中的wibble函数重命名为wobble另一模块wobble.gleam中的wibble.wibble()调用会同步更新为wibble.wobble()且 import 语句保持正确// wibble.gleam pub fn wobble() { wobble() } // wobble.gleam import wibble pub fn main() { wibble.wobble() }查找引用语言服务器新增对值values和类型types的引用查找能力既支持模块内查找也支持跨模块查找与重命名、跳转定义共同构成完整的符号导航体验。新 code action 一览1. 展开模式中的..为全部被忽略字段对let Pokemon(..) todo中的..触发 code action会展开为显式字段列表pub type Pokemon { Pokemon(id: Int, name: String, moves: List(String)) } pub fn main() { let Pokemon(id:, name:, moves:) todo }2. Generate JSON encoder 改为结构感知为自定义类型生成的 JSON encoder 从逐字段展开改为先解构再编码一旦类型新增字段生成的代码会编译失败提醒开发者重新执行 code action避免漏编码新字段fn encode_person(person: Person) - json.Json { let Person(name:, age:) person json.object([ #(name, json.string(name)), #(age, json.int(age)), ]) }3. 移除所有echo可一键移除模块中的所有调试echo既支持管道步骤形式| echo也支持表达式前置形式echo 1 2删除后管道与表达式保持完整合法。4. 运算符修正Float 运算符误用于 Int 值时一键替换为正确的 Int 运算符11 . 1→11 1Int 运算符误用于 Float 值时一键替换为正确的 Float 运算符1.1 10.0→1.1 . 10.0用拼接字符串报错时一键改为Hello, Jak→Hello, Jak。这些 code action 与上文更友好的类型错误信息直接呼应编译器负责准确报错并给出建议语言服务器负责把建议一键落地。5. 表达式提升为常量const支持把表达式提取为模块级const多次触发即可逐一提升const values [#(a, 0), #(b, 1), #(a, 2)] const string a pub fn main() { values | key_filter(string) }6. 包裹为块block选中 case 分支的右侧表达式或赋值表达式的值可将其包裹进块中方便继续添加多条表达式case pokemon_type { Water - { soak() } Fire - burn() }7. Generate function 智能命名参数根据调用处的标签与变量名生成函数签名例如greet(language, name: Louis)会生成pub fn greet(language: String, name name: String) - a { todo }8. 其余细节调整Generate JSON encoder code action仅在项目依赖中安装了gleam_json包时提供避免生成无法编译的代码Rewrite fromuse code action 只在光标位于use表达式首行时触发防止误触发。容器镜像与供应链安全容器镜像开始包含Software Bill of MaterialsSBoM软件物料清单与SLSA Provenance供应链出处证明信息。这意味着基于 Gleam 官方容器镜像构建的应用其依赖组成与构建出处可以被审计与验证符合现代软件供应链安全Supply Chain Security最佳实践。正式版 Bug 修复盘点除上述新特性外v1.10.0 还修复了一批影响日常开发的问题按模块归类如下格式化与echo修复echo对首元素为原子atom的元组格式化不正确的问题修复echo在管道前使用时Erlang 目标会生成非法代码的问题v1.9.1 修复项v1.10 延续改进echo打印管道的格式化效果v1.9.1 修复项。构造器与参数修复自定义类型变体构造器定义中带标签参数之后允许出现不带标签参数的问题v1.10 起禁止。Code action 相关修复 Convert to pipe 在函数的第一个参数本身是管道时生成非法代码的问题修复 Convert to pipe 作用于函数或 record capture 时生成非法代码的问题修复 Inline variable 在 record update 内部使用时失效的问题修复 Rewrite to pipe 在管道参数是二元运算时生成非法代码的问题。类型系统与模式匹配修复let assert赋值上变体推断不生效的问题修复let assert作为块内唯一表达式时不执行断言匹配的问题。构建与缓存修复文件被临时移动或删除后即使依赖已变化也不会重新编译的问题修复构建工具锁定 build 目录失败但不报错的问题修复语言服务器过于积极地重新编译、未充分利用先前编译缓存的问题修复 build 目录被删除如执行gleam clean后语言服务器停止工作的问题修复发布时多顶层模块检查会误打警告的问题。JavaScript 代码生成修复echo生成的 JavaScript 代码在模块内定义了console、process函数或Object、Deno自定义类型变体时发生名称冲突的问题。语言服务器细节修复补全autocomplete在模块选择module select场景下会建议 prelude 类型和值的问题修复 unqualify 类型/值的 code action 在目标已导入的情况下重复添加无限定导入的问题修复以0x_、0o_、0b_开头的数字编译到 JavaScript 时报语法错误的问题。小结与升级建议v1.10 是一次典型的编译器 工具链 编辑器体验三位一体更新编译器在诊断能力不可达分支、未使用递归函数、运算符错误建议与代码生成IIFE 消除、位数组增强上均有实质进展构建工具在导出流程双入口脚本、package-information与发布认证HEXPM_API_KEY上更贴近实际部署场景语言服务器则通过跨模块重命名、引用查找和一批高度实用的 code action把能提示升级为能自动改。对使用者而言升级到 v1.10.0 后值得立刻验证的几件事项目是否出现新的未使用函数/不可达分支警告可能暴露存量死代码发布脚本中是否仍依赖已弃用的HEXPM_USER/HEXPM_PASS应尽快迁移到HEXPM_API_KEY以及体验跨模块重命名与运算符修正 code action 带来的编辑效率提升。完整变更细节可查阅仓库内的 changelog/v1.10.md各功能对应实现可继续深入 compiler-core/src/call_graph.rs、compiler-cli/src/export.rs 与 language-server/src/code_action.rs 等源码文件。【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表