Appearance
工具链设计
目标
Qlang 不是“只有一个编译器二进制”的项目,而是一整套开发体验工程。工具链应围绕统一 CLI 和共享语义数据库展开。
统一入口
建议统一入口命令为 ql,由它驱动各子工具:
ql newql initql buildql runql testql checkql fmtql docql benchql cleanql ffi
这样可以减少工具数量膨胀,让使用者把它当成一个系统,而不是一堆松散命令。
子工具
ql check
当前 Phase 1 的 ql check 已经是一个真实可用的前端入口,而不是占位命令。它现在负责:
- 读取单个
.ql文件并执行 lexer / parser 验证 - 对目录执行批量检查
- 输出带稳定 span 的语法错误定位
当前目录扫描策略也已经收紧,避免把仓库噪音当成真实源码:
- 会跳过
target、node_modules、dist、build、coverage - 会跳过隐藏目录
- 会跳过仓库里的
fixtures/和临时测试目录,例如ramdon_tests/ - 如果用户显式传入某个 fixture 文件或 fail fixture 目录,仍然允许直接检查
这个策略不是“保守”,而是为了避免 ql check . 在仓库根目录误扫失败夹具、构建产物和杂项测试目录,污染真实前端回归结果。
qlsp
LSP 服务端,复用编译器 HIR 与查询系统,支持:
- go to definition
- find references
- hover
- completion
- semantic tokens
- rename
- code action
- diagnostics
qfmt
格式化器必须尽早做,并尽量做到:
- 输出稳定
- 风格单一
- 对 AST 变化敏感度低
现代语言生态一旦放任格式风格分裂,后面会一直付成本。
当前阶段 qfmt 已覆盖的语法切片包括:
- 基础声明:
const、static、type、opaque type - 可调用声明:
fn、traitmethod、impl、extend、extern - 类型表达式:named type、tuple、callable type、声明泛型、
where - 表达式:调用、成员访问、结构体字面量、闭包、
unsafe、if、match - 控制流:
while、loop、for、for await - 模式:tuple、path、tuple-struct、struct、字面量、
_
Phase 1 结束后,qfmt 的下一步重点不是增加风格选项,而是跟随后续 HIR / diagnostics 演进,保持语法扩展时的稳定输出与可维护实现。
当前已验证命令
截至 2026-03-25,当前前端基线已经反复验证过以下命令:
cargo fmtcargo testcargo run -p ql-cli -- check fixtures/parser/pass/basic.qlcargo run -p ql-cli -- check fixtures/parser/pass/control_flow.qlcargo run -p ql-cli -- check fixtures/parser/pass/phase1_declarations.qlcargo run -p ql-cli -- check target/review/if_empty_block.qlcargo run -p ql-cli -- check target/review/while_empty_block.qlcargo run -p ql-cli -- check target/review/match_empty_arms.qlcargo run -p ql-cli -- check target/review/one_tuple_type.qlcargo run -p ql-cli -- fmt fixtures/parser/pass/phase1_declarations.qlcargo run -p ql-cli -- fmt target/review/one_tuple_type.ql
qdoc
文档生成器负责:
- 从公共 API 提取签名
- 展示效果、错误、trait 约束和 FFI 标记
- 输出静态站点内容
测试工具
ql test 不只是运行单元测试,还应逐步支持:
- UI tests
- doc tests
- integration tests
- benchmark harness
包与工作区
Qlang 应提供统一 manifest,例如 qlang.toml,支持:
- package metadata
- dependencies
- features
- build profiles
- ffi libraries
- workspace members
工作区模型必须在早期就纳入,因为编译器、标准库、示例、FFI 包和工具链本身都会依赖它。
借鉴 TypeScript 的 project references,Qlang 还应支持显式项目引用图:
- 工作区成员能声明上游接口依赖
- 增量构建优先基于接口产物判断失效范围
- LSP 可直接消费依赖包的公共 API 元数据
接口产物
Qlang 建议为每个包输出公共接口产物,例如 .qi 文件:
- 包含公共类型、函数签名、trait、effect、布局约束等元数据
- 供下游类型检查和 LSP 使用
- 避免每次都重新解析全部依赖源码
这相当于把 TypeScript 的 declaration emit 和 project references 经验,转化为适合编译型系统语言的工程能力。
编辑器体验
LSP 的目标不是“有就行”,而是从第一阶段就支撑日常开发:
- 补全要基于真实类型,不是纯文本猜测
- 报错位置要稳定
- rename 要有跨文件可信度
- code action 要能生成
match分支、导入、trait stub
Qlang 的目标不是“有一个能用的 LSP”,而是像 TypeScript 一样,把语言服务当成语言本体的一部分来设计。
发布与生态
P1 之后可以逐步加入:
- package registry
- lockfile
- binary caching
- doc hosting
- template generator
但这些必须建立在前面的语义和构建基础上,而不是为了“看起来像成熟生态”提前堆功能。