ARTICLE DETAIL

资讯详情

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

Sway 代码格式化工具 swayfmt 完全指南:架构、配置与 forc-fmt 实战

Sway 代码格式化工具 swayfmt 完全指南:架构、配置与 forc-fmt 实战 Sway 代码格式化工具 swayfmt 完全指南架构、配置与 forc-fmt 实战【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway本指南系统讲解 Sway 语言的官方代码格式化工具swayfmt从它与forc-fmt插件的关系、安装与命令行用法到swayfmt.toml配置体系的九大配置节与全部默认值再到基于sway_parseAST 的格式化工作流与测试方法论。读完本文你将能够配置、运行并扩展 Sway 代码的格式化能力让智能合约代码风格统一、可读性更高。swayfmt 是什么swayfmt是 Sway 编程语言Fuel 生态智能合约语言的官方格式化库其定位是根据样式指南格式化 Sway 代码见 swayfmt/README.md。在实现理念上它明确参考了 Rust 社区的rustfmt——swayfmt/src/lib.rs 的模块注释写道Based onrustfmt,swayfmtaims to be a transparent approach to formatting Sway code基于rustfmtswayfmt旨在提供一种透明的 Sway 代码格式化方式。swayfmt以 Rust 库的形式实现作为工作区成员发布在Cargo.toml中包名swayfmt描述为 Sway language formatter。它本身不是命令行工具真正面向用户的入口是forc-fmt插件forc-plugins/forc-fmt/后者把swayfmt的能力封装成了forc的子命令。两者关系如下swayfmt格式化核心库负责解析 Sway 源码、按样式指南重排输出、管理配置forc-fmtforc插件二进制负责 CLI 参数解析、项目/工作区发现、文件读写与 diff 展示并额外用taplo格式化Forc.toml清单文件。安装与快速开始通过 fuelup 安装 forc-fmt对于普通使用者推荐通过 Fuel 工具链管理器fuelup安装forc-fmt插件安装后即可作为forc fmt子命令使用fuelup component add forc-fmt安装完成后在任何 Sway 项目包含Forc.toml的目录中运行forc fmt即可递归发现项目内的.sw源文件并统一格式化。从源码构建与手动运行如果你想基于本仓库构建或手动试验需要先安装 Rust 工具链然后克隆仓库后执行# 运行 swayfmt 自身的测试套件 cd swayfmt cargo test手动运行格式化器的方式来自 swayfmt/CONTRIBUTING.md把一段 Sway 代码粘贴到my_file.sw然后在仓库根目录用 cargo 直接跑forc-fmt二进制# 在 Sway 仓库根目录执行 cargo run --binforc-fmt my_file.sw与 rustfmt 的定位差异需要特别注意的是swayfmt并不追求做到与rustfmt完全等同的可配置性。贡献文档明确说明swayfmt/CONTRIBUTING.md请记住swayfmt的目标并非与rustfmt完全同构地可配置某些请求的功能在达成共识之前可能不会实现。因此在迁移 Rust 项目的格式化习惯时应以swayfmt的实际能力为准。forc-fmt 命令行实战forc-fmt是使用clap定义的 forc 插件其 CLI 参数完整定义在 forc-plugins/forc-fmt/src/main.rs 中。核心参数如下参数短格式说明--check-c检查模式输入已格式化则退出码为 0需要格式化则退出码为 1 并打印 diff--path PATH-p指定项目目录不指定时使用当前工作目录--file FILE-f仅格式化单个.sw文件使用默认配置不依赖Forc.toml--experimental/--no-experimental—控制实验性语言特性的启用来自sway_features::CliFields官方cli_examples!宏中给出的典型用法见同一文件的示例块# 在当前目录运行检查模式 forc fmt --check forc fmt -c # 针对单个文件格式化 forc fmt --file ./src/main.sw forc fmt -f ./src/main.sw # 针对指定目录格式化 forc fmt --path ./my_project forc fmt -p ./my_project检查模式--check--check是 CI 中最常用的模式。forc-fmt在检查模式下比较源文件内容与格式化结果若不一致则打印彩色 diff 并以错误退出完全格式化退出码 0存在格式化违规打印 diff并以Files contain formatting violations. 的错误信息退出退出码 1。diff 的展示逻辑在 forc-plugins/forc-fmt/src/main.rs 的display_file_diff函数中实现它用prettydiff逐行对比新增行以绿色前缀打印、删除行以红色-前缀打印且最多只展示 100 处更新避免输出过载。文件格式化的安全检查在写入文件之前forc-fmt会调用forc_util::fs_locking::is_file_dirty检查目标文件是否被编辑器打开且含有未保存的修改若存在未保存改动会直接报错中止从而避免覆盖用户在编辑器中的工作成果。项目与工作区的格式化策略forc-fmt对三种输入场景采取不同策略均在 forc-plugins/forc-fmt/src/main.rs 中实现单文件--file校验后缀为 Sway 文件后直接调用format_file单个包通过ManifestFile::Package分支调用format_pkg_at_dir收集该包内所有.sw文件借助get_sway_files逐一格式化最后用taplo格式化该包的Forc.toml工作区通过ManifestFile::Workspace分支调用format_workspace_at_dir。它先格式化工作区根目录下散落的 Sway 文件再用get_sway_dirs递归搜索所有含Forc.toml的子目录分别格式化子目录没有自己的swayfmt.toml时会继承工作区根目录的配置优先级为成员目录 工作区根目录 默认值代码注释明确说明最后格式化根Forc.toml。此外无论包还是工作区Forc.toml清单文件都会交给taplo格式化器处理例如统一缩进、按字母序重排键值见format_manifest与测试函数test_forc_alphabetization。swayfmt.toml 配置体系swayfmt的配置通过名为swayfmt.toml的文件声明它位于 Sway 项目根目录swayfmt/src/lib.rs 的文档注释以及 swayfmt/src/constants.rs 中的SWAY_FORMAT_FILE_NAME常量均可确认。默认格式化不需要该文件存在任何未声明的字段都回退到内置默认值——这也是透明设计的体现。配置的加载机制配置加载链路在 swayfmt/src/config/manifest.rs 中实现ConfigOptions是swayfmt.toml的直接映射包含九个可选的配置节serde(rename_all snake_case)ConfigOptions::from_dir通过sway_utils::find_parent_dir_with_file向上查找最近的swayfmt.toml因此子目录中的项目可以继承父目录配置解析使用serde_ignored::deserialize遇到未知字段会打印黄色警告 found unusable configuration而不是直接报错保证了对未来版本的向前兼容Config::from_opts把可选值与内置默认值合并生成最终生效的ConfigWhitespace、Imports、Ordering、Items、Literals、Expressions、Heuristics、Structures、Comments九个字段。Formatter::from_dir则在 swayfmt/src/formatter/mod.rs 中把两者串起来找到配置就用配置ConfigError::NotFound则使用Config::default()。九大配置节详解以下所有默认值均来自各配置模块与 swayfmt/src/constants.rs。1. whitespace空白与换行字段默认值说明max_width100每行最大宽度超过后触发折行hard_tabsfalse是否用制表符缩进对齐仍用空格tab_spaces4一个 Tab 对应的空格数newline_styleAuto换行风格Auto按源码自动探测、WindowsCRLF、UnixLF、NativeWindows 上 CRLF其余 LFindent_styleBlock缩进风格Visual首行与花括号同行后续行与首行对齐或Block首行换行、整体块缩进newline_threshold1语句之间允许的最大连续空行数超出后折叠到阈值newline_style的自动探测逻辑在 swayfmt/src/config/whitespace.rs 中NewlineSystemType::auto_detect_newline_style查找源码第一个\n若其前一个字符是\r则判定为 Windows否则为 Unix若全文没有换行则回退到平台原生风格。[whitespace] max_width 100 tab_spaces 4 hard_tabs false newline_style Auto indent_style Block newline_threshold 12. imports导入语句字段默认值说明group_importsPreserve导入分组策略Preserve保留现有分组、StdExternalCrate分为 std/core/alloc、其他、self/crate/super 三组、One全部合并为一组imports_granularityPreserve导入合并粒度Preserve、Crate每个 crate 一条 use、Module每个模块一条、Item每个导入项一条、One一条 use 包含全部imports_indentBlock导入的缩进风格复用IndentStyle3. ordering排序字段默认值说明reorder_importstrue按字母序重排 import 语句reorder_modulestrue在分组内按字母序重排 module 语句reorder_impl_itemsfalse是否重排impl内的条目4. items顶层条目字段默认值说明item_brace_styleSameLineWhere顶层条目fn、impl等左花括号位置AlwaysNextLine、PreferSameLine、SameLineWhere默认同行走但存在 where 子句时强制换行blank_lines_upper_bound1条目之间允许的最大空行数blank_lines_lower_bound0条目之间必须保留的最小空行数empty_item_single_linetrue空体函数与 impl 是否单行显示5. literals字面量字段默认值说明format_stringsfalse是否在必要时格式化字符串字面量hex_literal_casePreserve十六进制字面量大小写Preserve保持原样、Upper统一大写、Lower统一小写6. expressions表达式与标点字段默认值说明expr_brace_styleAlwaysSameLine条件表达式if、match等左花括号风格AlwaysSameLineKRRust 社区默认、ClosingNextLineStroustrup、AlwaysNextLineAllmantrailing_semicolontrue在break、continue、return后补尾分号space_before_colonfalse冒号前是否留空格space_after_colonfalse冒号后是否留空格type_combinator_layoutWide类型组合符周围空白Compressed/无空格、Wide、有空格spaces_around_rangesfalse..与..范围运算符两侧是否留空格match_block_trailing_commafalse块体 match 分支非块体不受影响末尾是否加尾逗号match_arm_leading_pipeNevermatch 分支前导竖线Always全部加、Never全部不加、Preserve保留现有force_multiline_blocksfalse是否强制把多行闭包体与 match 分支用块包裹fn_args_layoutTall函数参数布局Compressed尽量单行、Tall空间足够则横向、否则纵向、Vertical每项独立一行fn_single_linefalse单表达式函数是否单行显示7. heuristics宽度启发式字段默认值说明heuristics_prefScaled启发式等级Off关闭所有启发式、Max使用最大宽度、Scaled基于max_width缩放默认阈值use_small_heuristicstrue是否对满足小启发式判断的条目/表达式使用紧凑格式在Scaled模式下swayfmt/src/config/heuristics.rs 的WidthHeuristics::scaled会按max_width / 100的比例缩放以下默认阈值超出阈值即回退到纵向布局启发式宽度默认值100 列时含义fn_call_width60函数调用参数宽度attr_fn_like_width70类函数属性参数宽度structure_lit_width18结构体字面量体宽度structure_field_width35结构体字段宽度collection_width80数组/集合字面量宽度chain_width60方法链单行最大长度single_line_if_else_max_width50单行 if-else 最大长度0 表示总是折行short_array_element_width10数组元素判定为短的宽度阈值8. structures用户自定义结构字段默认值说明field_alignmentOff字段对齐阈值AlignFields(n)差异在阈值内时对齐字段或Offstruct_lit_single_linetrue小的结构体字面量是否单行显示9. comments注释字段默认值说明wrap_commentsfalse是否折行注释以适配行宽comment_width80注释最大长度仅当wrap_comments true时生效normalize_commentsfalse在可能的情况下把/* */注释转换为//注释一份完整的 swayfmt.toml 示例综合以上九个配置节可以写出如下完整配置[whitespace] max_width 100 tab_spaces 4 hard_tabs false newline_style Auto indent_style Block newline_threshold 1 [imports] group_imports StdExternalCrate imports_granularity Item imports_indent Block [ordering] reorder_imports true reorder_modules true reorder_impl_items false [items] item_brace_style SameLineWhere blank_lines_upper_bound 1 blank_lines_lower_bound 0 empty_item_single_line true [literals] format_strings false hex_literal_case Preserve [expressions] expr_brace_style AlwaysSameLine trailing_semicolon true space_before_colon false space_after_colon false type_combinator_layout Wide spaces_around_ranges false match_block_trailing_comma false match_arm_leading_pipe Never force_multiline_blocks false fn_args_layout Tall fn_single_line false [heuristics] heuristics_pref Scaled use_small_heuristics true [structures] field_alignment Off struct_lit_single_line true [comments] wrap_comments false comment_width 80 normalize_comments false格式化工作流从源码到输出swayfmt的格式化核心是一条解析 → 格式化 → 后处理的流水线可以在 swayfmt/src/formatter/mod.rs 与 swayfmt/src/parse.rs 中完整追踪。解析阶段swayfmt/src/parse.rs 的parse_file调用sway_parse::parse_file把 Sway 源码解析成带注释的 ASTAnnotatedModulelex则调用sway_parse::lex_commented得到保留注释的 token 流CommentedTokenStream。整个解析过程通过Handler收集诊断错误若存在错误则返回ParseFileError而不会产出半成品格式。格式化阶段Formatter::format的入口swayfmt/src/formatter/mod.rs依次执行应用宽度启发式根据config.heuristics.heuristics_pref与max_width计算WidthHeuristics并写入Shape建立注释上下文with_comments_context通过CommentMap::from_src建立源码字节区间到注释的映射供后续在 AST 结构中重放注释逐项格式化遍历 AST 中的条目与表达式调用各实现Formattrait 的格式化器items/、module/、utils/目录下的模块把内容写入缓冲。Formattrait 定义于 swayfmt/src/formatter/mod.rs签名如下pub trait Format { fn format( self, formatted_code: mut FormattedCode, formatter: mut Formatter, ) - Result(), FormatterError; }处理换行与注释映射利用removed_spans记录格式化过程中被移除的字节区间例如单元素导入被折叠时去掉的花括号handle_newlines据此修正注释的 span 映射应用换行风格apply_newline_style根据newline_style配置把统一生成的换行转换为\n或\r\n。Formatter结构体swayfmt/src/formatter/mod.rs持有source_engine源码引擎、shape当前缩进与宽度状态、config最终生效配置、comments_context、experimental实验特性开关与removed_spans。Shape负责维护缩进块层级indent()/unindent()则对应进入/退出代码块的缩进调整。一个格式化行为的实例swayfmt/tests/mod.rs 中的const_spacing测试直观展示了标点规范化的效果// 输入未格式化 contract; pub const TEST:u1610; // 期望输出 contract; pub const TEST: u16 10;可见swayfmt会统一类型标注冒号两侧空格与赋值号两侧空格。同文件的module_doc_comments_persist、conserve_pub_mod测试则分别验证了模块级文档注释的保留与pub mod声明的原样输出——说明格式化不是丢掉一切重写而是尽可能在统一风格的同时保留源码语义与注释。测试与贡献测试方法论swayfmt的测试分为两层swayfmt/CONTRIBUTING.md单元测试位于各实现模块旁的tests.rs如items/item_struct/tests.rs针对单个条目或表达式借助test_macros中的宏进行断言集成测试位于 swayfmt/tests/ 目录验证整段源码能否被正确解析并格式化。swayfmt/tests/mod.rs 的check()函数是所有集成测试的统一入口其核心设计是两次格式化幂等性校验fn check_with_formatter(unformatted: str, expected: str, formatter: mut Formatter) { let first_formatted Formatter::format(formatter, unformatted.into()).unwrap(); assert_eq_pretty!(first_formatted, expected); // 第二次格式化结果必须与第一次一致确保格式化是幂等的 let second_formatted Formatter::format(formatter, first_formatted.as_str().into()).unwrap(); assert_eq_pretty!(second_formatted, first_formatted); }第一次校验输入 → 期望输出第二次校验输出再次格式化不变。幂等性保证了格式化器不会在cargo fmt之类的工作流中产生反复改动的抖动。贡献要点提交新功能或修复 bug 时应尽量附带相应测试调整格式化空白或追加char时若sway_ast未提供对应常量应把新字符定义为一个constswayfmt/CONTRIBUTING.md 明确要求代码风格上应避免不必要的内存重分配如String::new()、.clone()与破坏性操作如.pop()追加FormattedCode优先使用std::fmt::Write宏功能讨论可参考rustfmt作为权威参照但如前所述swayfmt不承诺与rustfmt同等可配置。已知限制从 forc-plugins/forc-fmt/src/main.rs 的注释可知当前版本对不完整或无效的 Sway 代码格式化支持尚未实现源码中留有 TODO 并关联到 sway 仓库的 issue遇到解析失败的输入时会直接报错 Failed to compile 并跳过格式化。因此在使用forc fmt前请确保待格式化代码本身是可解析的。此外配置系统对未知配置字段仅给出警告而非报错这也是为了兼容未来版本新增的配置项。总结swayfmt是 Sway 智能合约开发工具链中负责代码风格统一的关键一环它以上游sway_parse的 AST 为基础提供九大类、数十个可调配置项默认值经过精心设计可直接开箱即用forc-fmt插件则把该能力无缝接入forc工作流支持单文件、单包与工作区三种粒度的格式化并借助--check模式与 diff 输出轻松集成进 CI。无论是日常开发中的forc fmt还是想在项目中固化团队代码风格本文所梳理的配置项、默认值与源码工作流都能帮助你快速上手。【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表