ARTICLE DETAIL

资讯详情

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

Gleam v1.5.0 更新解读:构建工具、版本约束治理、编译器诊断与语言服务器全面升级

Gleam v1.5.0 更新解读:构建工具、版本约束治理、编译器诊断与语言服务器全面升级 Gleam v1.5.0 更新解读构建工具、版本约束治理、编译器诊断与语言服务器全面升级【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam本文基于当前仓库 changelog/v1.5.md 中的官方变更日志结合 compiler-cli、compiler-core 源码实现系统梳理 Gleam v1.5.02024-09-19 发布带来的构建工具改进、gleam.toml版本约束治理、编译器错误诊断增强、格式化器与语言服务器新能力。读完本文你将掌握 v1.5.0 中每个新特性对应的实际命令、语法写法与底层实现依据可直接应用到项目升级与日常开发中。版本发布概览rc1 → rc2 → 正式版v1.5.0 采用「候选版先行、快速收敛」的发布节奏版本日期定位v1.5.0-rc12024-09-14功能候选版集中引入构建工具、编译器、格式化器、语言服务器新特性v1.5.0-rc22024-09-18修复 rc1 中发现的两个格式化/编译器 bugv1.5.02024-09-19正式发布rc2 修复的两个问题分别是格式化器无法正确处理嵌套元组访问nested tuple access的格式化以及多构造子multi-variant自定义类型的访问器无法被正确检测。前者涉及格式化与类型推导对x.0.1这类嵌套访问的解析后者关乎编译器对自定义类型字段访问的静态分析。附v1.5.0 正式版之后还跟随了 v1.4.1 补丁2024-08-04修复了 LSP 对私有类型记录访问器record accessor补全失效的问题即同模块内访问私有类型的记录字段时 IDE 不再提示补全。构建工具Build Tool改进1.--no-print-progress静默构建新增--no-print-progress标志用于抑制构建过程中输出到终端的进度消息适合 CI 流水线、脚本化构建或需要干净日志输出的场景。该标志被接入编译主流程在 compiler-cli/src/build.rs 中可以看到其底层实现let telemetry: static dyn Telemetry if options.no_print_progress { NullTelemetry } else { cli::Reporter };即开启该标志后编译器使用NullTelemetry替换默认的Reporter从而完全静默进度输出。该标志同时贯穿多个子命令在 compiler-cli/src/lib.rs 中为build、run、test等命令统一注册#[arg(long, help no_print_progress_doc())]并传入command_build等核心调用点。gleam build --no-print-progress gleam run --no-print-progress2.gleam run -m项目报错时仍可运行依赖模块此前只要自己项目代码存在编译错误gleam run就无法执行任何模块v1.5.0 起当使用gleam run -m module运行依赖包中的模块时即使根项目代码有编译错误也能继续。其原理见 compiler-core/src/build/project_compiler.rs编译根包时目标支持TargetSupport是否强制取决于运行场景——如果通过gleam run -m运行的是依赖模块则不强制根包函数全部具备当前目标的实现因为依赖模块不可能调用根包的函数根包编译失败不影响它运行而编译依赖时本就使用TargetSupport::NotEnforced只要依赖暴露的 API 未被根包实际使用即可。3. OTP 应用树优雅关闭main函数退出时OTP 应用树application tree现在会被优雅地关闭graceful shutdown而不是直接中断。这对使用 Erlang 目标、依赖 OTP 监督树清理资源的项目尤为重要保证退出时的资源释放与状态落盘过程完整执行。4. 运行时错误打印改进运行时错误runtime errors的打印输出得到整体改进包括**链接进程linked processes**产生的错误。这意味着在多进程协作场景下进程异常退出的错误信息现在能更清晰地呈现。5. HTML 文档侧边栏换行优化生成的 HTML 文档中模块名在侧边栏sidebar的换行策略改为优先在/处换行避免出现难看的断词提升长模块路径如gleam/erlang/process在窄栏中的可读性。版本约束治理gleam fix与发布校验v1.5.0 在「项目声明的 Gleam 版本约束」与「实际使用的语言特性」之间建立了强一致性管理包含三个相互配合的机制1. 编译器推断最小所需版本并告警编译器现在可以推断你的代码所需的最低 Gleam 版本并在项目的gleam版本约束未包含该版本时发出Incompatible gleam version range警告。该警告的完整诊断文本在 compiler-core/src/warning.rs 中实现例如gleam.toml声明gleam 1.1.0而代码使用了 v1.4.0 才引入的常量字符串拼接// 常量字符串拼接是 v1.4.0 引入的特性 pub const greeting hello world!编译即得到警告warning: Incompatible gleam version range ┌─ /path/to/src/datalog.gleam:1:22 │ 1 │ pub const greeting hello world! │ ^^^^^^^^^^^^^^^^^^^^ This requires a Gleam version 1.4.0 Constant strings concatenation was introduced in version v1.4.0. But the Gleam version range specified in your gleam.toml would allow this code to run on an earlier version like v1.1.0, resulting in compilation errors! Hint: Remove the version constraint from your gleam.toml or update it to be: gleam 1.4.0该机制在源码中维护了一张「特性 → 引入版本」的映射表FeatureKind涵盖 BitArray 段省略标注、嵌套元组访问、internal注解、record update 变体推断、let assert 自定义 panic 消息、JavaScript 非对齐 BitArray、常量记录更新、常量列表前置等几十项特性每一项都对应一个独立的最小版本记录编译期据此精确告警。2.gleam fix自动修正版本约束gleam fix命令新增能力当上述警告存在时自动把gleam.toml中的gleam版本约束更新为推断出的最小所需版本。实现在 compiler-cli/src/fix.rs先以收集警告的方式编译项目VectorWarningEmitterIO暂存全部警告从警告中筛选FeatureRequiresHigherGleamVersion取其中最大的minimum_required_versionminimum_required_version_from_warnings用reduce(std::cmp::max)聚合通过toml_edit解析并改写gleam.toml中的gleam {minimum_required_version}然后写回文件。gleam fix # 输出示例- Set required Gleam version to 1.4.03. 发布时的双重防线配合上述编译期警告构建工具在**发布publish**阶段增加两条硬性校验若项目的gleam版本约束可能覆盖一个不支持该包所用特性的编译器版本则拒绝发布若项目完全没有声明gleam版本约束则在发布前自动推断并写入gleam.toml。这保证发布到 Hex 的包声明了与代码实际特性相匹配的编译器版本下限避免下游用户用旧编译器安装后出现编译失败。编译器Compiler新特性1. BitArray 段可省略:utf8标注字面量字符串作为 BitArray 段时:utf8选项现在可以省略// 以下两种写法等价 Hello, , world Hello:utf8, :utf8, world:utf8从 compiler-core/src/warning.rs 的特性说明可以看到该能力作为FeatureKind::UnannotatedUtf8Segment记录The ability to omit theutf8annotation for string segments同样受最小版本推断机制保护该特性要求 v1.5.0。2. 匿名函数推断改进记录/元组实参免标注此前匿名函数若以记录或元组作为实参类型往往需要手动标注v1.5.0 起以下两种场景均可自动推断直接调用场景无需任何注解fn(x) { x.0 }(#(1, 2)) // ^ 不再需要标注参数类型管道场景pub type User { User(name: String) } pub fn main() { User(Giacomo) | fn(user) { user.name } // ^^^^ 不再需要标注参数类型 | io.debug }这消除了管道链中常见的冗余类型注解让|配合内联函数的写法更自然。3. 非穷尽模式匹配错误全面改进非穷尽case的错误报告在 v1.5.0 有多处强化缺失变体使用「出错模块」的语法打印此前缺失模式按定义模块的命名空间打印v1.5.0 起按出错文件自身的写法打印含限定名与否取决于出错模块的导入方式。例如import gleam/option pub fn main() { let an_option option.Some(wibble!) case an_option { option.None - missing } }错误提示缺失模式为option.Some(_)带限定名而不是裸的Some(_)error: Inexhaustive patterns ┌─ /path/to/src/prova.gleam:5:3 │ 5 │ ╭ case an_option { 6 │ │ option.None - missing 7 │ │ } │ ╰───^ This case expression does not have a pattern for all possible values. If it is run on one of the values without a pattern then it will crash. The missing patterns are: option.Some(_)缺失模式建议更精确空case现在会列出全部缺失变体而非笼统地建议_let a True case a {}error: Inexhaustive patterns ┌─ /src/file.gleam:3:3 │ 3 │ case a {} │ ^^^^^^^^^ This case expression does not have a pattern for all possible values. If it is run on one of the values without a pattern then it will crash. The missing patterns are: False True多主题 case 修复修复了对多个 subject 做非穷尽匹配时打印错误缺失模式的问题。4. 记录模式语法弃用Record(a ..)→Record(a, ..)旧写法Record(a ..)构造子后缺逗号直接跟..被弃用统一改为Record(a, ..)。词法层面..由Token::DotDot表示见 compiler-core/src/parse/lexer.rs而Wibble(field1: 0, ..)这类新写法在解析快照record_trailing_dot_dot_const.snap中可见。升级时需把Record(field ..)类模式改为Record(field, ..)。5. 更友好的语法与语义错误v1.5.0 为多种常见误用新增了针对性诊断模块名被当作值使用import gleam/list pub fn main() { list }error: Module list used as a value ┌─ /path/to/src/prova.gleam:4:3 │ 4 │ list │ ^^^^ Modules are not values, so you cannot assign them to variables, pass them to functions, or anything else that you would do with a value.在自定义类型里写函数疑似 OOP 类声明pub type User { User(name: String) fn greet(user: User) - String { hello user.name } }error: Syntax error ┌─ /path/to/src/prova.gleam:8:3 │ 8 │ fn greet(user: User) - String { │ ^^ I was not expecting this Found the keyword fn, expected one of: - } - a record constructor Hint: Gleam is not an object oriented programming language so functions are declared separately from types.误写if表达式Gleam 没有 if 表达式应使用casepub fn main() { let a if wibble { 1 } }error: Syntax error ┌─ /src/parse/error.gleam:3:11 │ 3 │ let a if wibble { │ ^^ Gleam doesnt have if expressions If you want to write a conditional expression you can use a case: case condition { True - todo False - todo } See: https://tour.gleam.run/flow-control/case-expressions/访问未导入模块时提示导入仅当存在同名导出类型/值的模块时给出提示pub fn main() { io.println(Hello, world!) }error: Unknown module ┌─ /src/file.gleam:2:3 │ 2 │ io.println(Hello, world!) │ ^^ No module has been found with the name io. Hint: Did you mean to import gleam/io?而访问io.non_existent()io模块本身不存在于依赖中则不给提示。同时改进了未知模块值的错误标题并为external使用未知 target 提供更好的错误信息。6. 编译进度输出改道 stderr编译器的进度消息从 stdout 改为输出到stderr。这使得gleam build output.log之类的重定向只保留程序自身输出如错误摘要之外的内容进度信息仍实时显示在终端也方便在 CI 中分离两类输出流。7. JavaScript 目标非字节对齐整数位模式编译期报错JavaScript 目标上BitArray 模式中非字节对齐non-byte aligned的整数此前会在运行时产生问题v1.5.0 起在编译期直接报告错误把隐患前移到类型检查阶段。注JS 目标上对齐整数与更宽 BitArray 表达式的限制机制后续版本持续完善仓库快照中可见相关requires_v1_9演进。格式化器Formatteruse表达式后自动补todo若use表达式是块中的最后一个表达式格式化器现在会自动在其后补上todo避免误以为块已完成pub fn main() { use user - result.try(fetch_user()) }格式化后变为pub fn main() { use user - result.try(fetch_user()) todo }这提醒开发者use展开后还有未写完的分支逻辑同时保证格式化结果始终是可编译的语法结构。语言服务器Language Server新能力1. 本地变量补全语言服务器现在可以在函数内部为局部变量提供补全IDE 中编写us时会提示当前作用域内已定义的user等局部绑定。2. 三个实用代码操作Code Action未使用值赋值给_对未使用值提示代码操作一键改写为_抑制警告。导入缺失模块对引用未导入模块的已有代码自动生成导入语句pub fn main() { io.println(Hello, world!) }一键应用后变为import gleam/io pub fn main() { io.println(Hello, world!) }补全 case 缺失模式将非穷尽 case 自动补全为穷尽版本let a True case a {}应用后变为let a True case a { False - todo True - todo }与编译器改进后的缺失模式建议见上文正好形成「诊断 → 修复」闭环。3. 补全与导航修复LSP 现在能正确显示Gleam prelude内置预置中值的补全修复了同模块内定义的external函数无法跳转到定义的问题修复了跳转到非限定函数定义时定位正确但停留在同一文件的问题修复了语言服务器与编译器在两个同名构造子存在时的崩溃v1.4.1 补丁修复了私有类型的记录访问器在 LSP 中不补全的问题。重点 Bug 修复清单除上述特性外v1.5.0 修复了以下值得关注的问题警告与错误输出换行修复警告打印在错误上方且之间无空行的问题重复构造子崩溃修复模式匹配含有重复名构造子的类型时编译器崩溃JS 常量中的记录构造子引用修复 JavaScript 常量中引用而非调用记录构造子可能生成非法代码HTML 文档源码链接修复 Codeberg、SourceHut、Gitea 上源码链接source links不正确Erlang 代码生成修复 BitArray 中丢弃 utf8 模式discard utf8 patterns的 Erlang 代码生成管道表达式推断修复管道表达式中函数调用的推断问题下划线开头变量名改进let some _func()、case { 1 - _func() }这类以_开头变量名用法的错误信息REBAR 环境变量路径修复REBAR_BARE_COMPILER_OUTPUT_DIR使用相对路径导致部分包编译失败未使用的限定构造子修复限定名qualified的未使用构造子不被报告为未使用未使用导入函数的 target 检查修复导入但未使用的函数不检查目标支持、可能生成非法代码的问题:与错误位置修复表达式中:、位置错误时语法错误信息不准确的问题。升级建议与影响小结写代码时BitArray 字符串段可去掉:utf8匿名函数配合管道处理记录/元组不再需要类型标注记录模式统一使用Record(a, ..)新语法。工程治理运行gleam fix让编译器自动修正gleam.toml的gleam版本约束CI 中可用--no-print-progress获得干净日志发布前留意构建工具的版本约束硬校验。IDE 体验升级到 v1.5.0 后本地变量补全、缺失模式补全、自动导入、未使用值改写等代码操作立即可用配合更精确的非穷尽匹配诊断日常开发效率明显提升。以上全部特性均可在本仓库对应源码中验证构建流程见 compiler-cli/src/build.rs 与 compiler-cli/src/lib.rs版本约束警告实现见 compiler-core/src/warning.rsgleam fix的自动修正见 compiler-cli/src/fix.rsgleam run -m的目标支持策略见 compiler-core/src/build/project_compiler.rs。【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表