factory
是一个结构化的、类型安全的源代码生成工具。它旨在替代(并改进)gyb
工具!
factory
由 swift-syntax
驱动,因此它会随着工具链一起发展。您不能使用 5.6.2 发行版本的工具链运行它,因为 5.6.2 工具链版本太旧,不支持 factory
安全转换源代码所需的 API。
当前的工具链版本锁定为
swift-DEVELOPMENT-SNAPSHOT-2022-12-17-a
由 factory
生成 的 Swift 文件仍然是向后兼容的,事实上,factory
的主要用例之一就是向后部署。
SPF 官方支持 Linux 和 macOS。
请注意,在 macOS 上,SPM 默认设置了错误的 @rpath
,因此您需要在构建产物目录中手动添加指向 lib_InternalSwiftSyntaxParser.dylib
的符号链接。
factory
的设计考虑了以下目标
模板文件应该看起来像普通的 .swift
文件,这样代码高亮器和 IDE 就不会出错。
模板应该是安全的,并禁止任意的字符串拼接或 token 替换。
模板应该与文档注释良好配合。
模板语法应该是最小化的、纯粹的附加性的,并且源代码生成工具应该接受并返回原生的 .swift
源代码,保持不变。
模板用户应该能够根据需要使用尽可能多或尽可能少的模板,并且在一个声明上使用模板不应增加文件中其余代码的认知负担。
模板系统应该引导用户尽可能少地使用模板,以满足他们的用例。
模板源代码应该是自解释的,并且对于从未听说过 swift-package-factory
的开发人员来说也应该是可以理解的。
模板用户应该能够*停止*使用模板系统,并且能够在任何时候承担维护生成的 .swift
文件的责任。
简而言之
extension Int
{
@matrix(__ordinal__: [i, j, k], __value__: [0, 1, 2])
@inlinable public
var __ordinal__:Int
{
__value__
}
@basis
let cases:[Never] = [a, b]
enum Cases:Int
{
@matrix(__case__: cases)
case __case__
}
@matrix(__case__: cases)
public static
var __case__:Self
{
Cases.__case__.rawValue
}
}
extension Int
{
@inlinable public
var i:Int
{
0
}
@inlinable public
var j:Int
{
1
}
@inlinable public
var k:Int
{
2
}
enum Cases:Int
{
case a
case b
}
public static
var a:Self
{
Cases.a.rawValue
}
public static
var b:Self
{
Cases.b.rawValue
}
}
查看 Examples
目录以了解如何使用 SPF!
factory
使用三个属性扩展了 Swift 语言
@basis
定义了一个 token 序列,用于在从模板生成声明时进行迭代。它可以应用于 let
绑定,并且必须使用数组字面量进行初始化。
它所附加的声明将从生成的 .swift
代码中删除,以及任何相关的注释和文档注释。
@matrix
复制它所附加的声明,以及任何相关的注释和文档注释。它接受 @basis
绑定或/和内联数组字面量作为参数,参数名称将成为循环变量的名称。如果给出多个 basis,@matrix
会将它们压缩在一起,并且如果它们的长度不同,则会丢弃尾部的 basis 元素。
@matrix
可以应用于 associatedtype
、actor
、class
、case
、enum
、extension
、func
、import
、init
、operator
、优先级组、protocol
、struct
、subscript
、typealias
、let
或 var
声明。
@retro
将具有主关联类型的协议降级为不具有任何关联类型的协议,并通过 #if swift(>=5.7)
来分隔这两个变体。它可以应用于至少具有一个主关联类型的 protocol
。
@retro
复制附加到原始 protocol
的任何注释和文档注释,并将它们包含在生成的 #if
代码块中。