FlatBuffers 代码格式规范指南:C++、Swift 与 TypeScript 的格式化与 Lint 实战
【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers
导读:本文以 FlatBuffers 仓库的 Formatters.md 为骨架,系统梳理该序列化库在 C++、Swift、TypeScript 三种语言上的格式化与 lint 工具链、命令与配置文件。你将掌握如何在提交 Pull Request 前对源码执行 clang-format、swiftformat 与 eslint,理解仓库内 scripts/clang-format-git.sh、swift.swiftformat、eslint.config.mjs 等配置的深层含义,并遵守"绝不格式化生成代码"这一关键纪律,从而以符合上游规范的代码顺利参与贡献。
一、总体原则:贡献前的格式纪律
FlatBuffers 是一个多语言序列化库,仓库根目录的 Formatters.md 面向所有潜在贡献者提出了两条通用要求:
- 提交 Pull Request 前,必须对自己修改的语言运行对应的 linter / formatter;
- 严禁对自动生成的代码执行格式化或 lint(DONT format/lint the generated code)。
第二条纪律尤为重要。FlatBuffers 的绝大多数目标语言代码(如tests/MyGame/Example/下的 Python、Java、Go、C# 等生成产物)都是由flatc编译器从.fbsschema 自动生成的,例如 tests/monster_test_generated.h、tests/monster_test_generated.ts 等。对生成代码做格式化会引入与编译器输出不一致的 diff,既污染提交历史,也让代码审查难以聚焦于真实改动。正因如此,仓库的格式化脚本都专门排除了生成文件(详见后文各语言小节)。
各语言的具体规则定义在各自独立的 formatter/linter 配置中,下面分别展开。
二、C++:clang-format + Google Style
C++ 是 FlatBuffers 的核心实现语言,其格式化工具是clang-format,风格基准为Google C++ Style Guide。
2.1 一键格式化脚本
仓库提供了两个脚本:
- scripts/clang-format-git.sh(官方推荐):基于
git clang-format,只格式化相对HEAD^有改动的代码,适合提交前使用:
sh scripts/clang-format-git.sh脚本内容如下:
# Running it twice corrects some bugs in clang-format. for run in {1..2} do git clang-format HEAD^ -- include/flatbuffers/* src/*.cpp tests/*.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp -f done git checkout include/flatbuffers/reflection_generated.h- scripts/clang-format-all.sh:不依赖 git 历史,直接对全部目标文件原地格式化:
sh scripts/clang-format-all.sh其内部同样是"运行两遍"(注释说明第一遍可能存在 bug,跑两遍才能修正),覆盖范围与 git 版一致:include/flatbuffers/*、src/*.cpp、tests/*.cpp、samples/*.cpp、grpc/src/compiler/schema_interface.h、grpc/tests/*.cpp。两个脚本最后都会执行git checkout include/flatbuffers/reflection_generated.h,显式恢复自动生成的 reflection 头文件,正是对"不改生成代码"原则的落地执行。
2.2 clang-format 配置
仓库根目录的 .clang-format 只有三行:
--- Language: Cpp BasedOnStyle: Google ...即:语言为 C++,直接继承 Google 风格。这意味着缩进、命名、指针引用位置、函数参数换行等全部遵循 Google C++ Style Guide 的默认 clang-format 规则,贡献者无需自定义额外选项。运行脚本前请确保本机已安装 clang-format(版本建议与上游 CI 保持一致,格式化效果在较新版本间基本稳定)。
2.3 相关源码佐证
格式化覆盖的核心目录正是库的主体实现:
- 头文件 include/flatbuffers/flatbuffers.h、include/flatbuffers/flatbuffer_builder.h;
- 编译器实现 src/flatc.cpp、src/idl_parser.cpp;
- 测试代码 tests/test.cpp、tests/monster_test.cpp 等。
这些文件在提交前都应保持 Google 风格整洁,以通过 CI 的格式检查。
三、Swift:swiftformat + swift.swiftformat
Swift 运行时(位于 swift/ 目录)使用swiftformat作为格式化工具。
3.1 安装与运行
swiftformat 的安装方式见其官方 README(可通过 Homebrew 等方式安装)。安装完成后,在仓库根目录执行:
swiftformat --config swift.swiftformat .命令使用根目录下的 swift.swiftformat 作为配置文件,递归处理整个仓库中的 Swift 文件。
3.2 配置解读
swift.swiftformat 是一份相当完整的格式化配置,值得逐段理解:
语言版本与基础排版:
--swiftversion 5.7 --indent 2 --maxwidth 80声明 Swift 5.7 语法基准,2 空格缩进,行宽上限 80 字符。
常用选项:
--self remove # 移除多余的 self(redundantSelf 规则) --importgrouping testable-bottom # import 分组排序(sortImports 规则) --trimwhitespace always # 始终清理行尾空白 --indentcase false # case 不额外缩进 --ifdef no-indent # #ifdef 块不缩进 --wraparguments before-first # 参数换行时对齐到第一个参数 --wrapparameters before-first # 函数声明参数同理 --closingparen same-line # 右括号紧跟最后一个参数同行 --funcattributes prev-line # 函数属性放上一行 --typeattributes prev-line # 类型属性放上一行启用的规则集:
--rules wrap,todos,anyObjectProtocol,redundantParens,redundantSelf,sortImports, strongifiedSelf,trailingCommas,trailingSpace,wrapArguments, wrapMultilineStatementBraces,indent,wrapAttributes,void,fileHeader --disable trailingclosures覆盖换行、TODO 注释规范化、AnyObject协议、冗余括号、冗余self、import 排序、尾逗号、行尾空格、多行语句花括号、缩进、属性换行、空Void、文件头等 16 项规则,并显式禁用trailingclosures。
排除生成代码与文件头:
--exclude **/*_generated.swift --exclude **/swift_code_*.swift --exclude **/*.grpc.swift --exclude **/Build/tests/**通过 glob 排除所有*_generated.swift(如 tests/swift/ 下的生成文件)、gRPC 生成文件与构建产物——再次印证了"生成代码不格式化"的仓库纪律。
最后用--header指定统一的 Apache License 2.0 文件头模板(Copyright 2024 Google Inc.),swiftformat 会自动为缺少头的新文件补齐。
四、TypeScript:eslint + eslint.config.mjs
TypeScript/JavaScript 部分使用eslint作为 linter。
4.1 运行命令
在仓库根目录执行:
eslint ts/** --ext .ts注意原文档该命令基于较旧的 eslint 写法(--ext .ts指定文件扩展名);当前仓库已升级到 eslint 9 扁平配置(flat config),因此也可以直接运行npx eslint ts达到同样效果——ts/package.json 中定义的lint脚本正是eslint ts:
"scripts": { "lint": "eslint ts", ... }4.2 配置解读
仓库根目录的 eslint.config.mjs 采用 eslint 9 推荐的扁平配置结构:
import globals from "globals"; import pluginJs from "@eslint/js"; import tseslint from "typescript-eslint"; export default [ {files: ["**/*.{js,mjs,cjs,ts}"]}, {languageOptions: { globals: {...globals.browser, ...globals.node} }}, pluginJs.configs.recommended, ...tseslint.configs.recommended, ];要点:
- 匹配范围覆盖
js/mjs/cjs/ts四种扩展名; - 全局变量同时声明浏览器与 Node 环境(FlatBuffers 的 TS 运行时需在两端运行);
- 叠加
pluginJs.configs.recommended(JS 推荐规则)与typescript-eslint的 recommended 规则集。
所需的 devDependencies(eslint、typescript-eslint、@eslint/js、@typescript-eslint/parser等)都声明在 ts/package.json 中,运行前执行npm install(或pnpm install,仓库提供 pnpm-lock.yaml)即可就绪。
五、生成代码保护:各语言的统一红线
无论使用哪种工具,FlatBuffers 都要求贡献者不触碰生成代码。汇总仓库中的落地方式:
| 语言 | 工具 | 生成代码保护机制 |
|---|---|---|
| C++ | clang-format | 脚本末尾git checkout include/flatbuffers/reflection_generated.h还原生成头文件 |
| Swift | swiftformat | --exclude **/*_generated.swift、--exclude **/*.grpc.swift等排除规则 |
| TypeScript | eslint | lint 仅指向ts/源目录(tests/ts/ 中的生成.ts不在ts/下) |
而flatc生成的代码(如 tests/monster_test_generated.h)统一由 scripts/generate_code.py 重新生成,贡献者不应手工修改。
六、提交前检查清单
基于上述内容,为 FlatBuffers 贡献代码前的格式化流程可归纳为:
- C++:安装 clang-format,运行
sh scripts/clang-format-git.sh(只格式化本次改动); - Swift:安装 swiftformat,在根目录运行
swiftformat --config swift.swiftformat .; - TypeScript:安装依赖后运行
npm run lint(即eslint ts)或npx eslint ts/** --ext .ts; - 通用纪律:绝不格式化/修改
*_generated.*等自动生成文件;只格式化自己改动涉及的语言; - 确认后再发起 Pull Request,避免因格式问题被 CI 拦截。
严格遵循 Formatters.md 与配套配置,既能保证提交质量,也让跨语言贡献者的代码风格与 FlatBuffers 上游保持一致。
【免费下载链接】flatbuffersFlatBuffers: Memory Efficient Serialization Library项目地址: https://gitcode.com/GitHub_Trending/fl/flatbuffers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考