factory is a structured, type-safe source generation tool. It is intended to be a replacement for (and improvement over) the gyb tool!
factory is powered by swift-syntax, so it evolves with the toolchain. You cannot run it with the 5.6.2 release toolchain, because the 5.6.2 toolchain is too old and does not support the API factory needs to transform your sources safely.
Swift files generated by factory are still backwards compatible, in fact one of the main use cases of factory is back-deployment.
Platforms
SPF officially supports Linux and macOS.
Please note that on macOS, SPM sets the wrong @rpath by default, so you will need to manually add a symlink to lib_InternalSwiftSyntaxParser.dylib inside your build artifacts directory.
Overview
factory was designed with the following goals in mind:
Template files should look like normal .swift files, so highlighters and IDEs don’t freak out.
Templates should be safe, and prohibit arbitrary string splicing or token substitutions.
Templates should work well with documentation comments.
Template syntax should be minimal, purely additive, and source generation tooling should accept and return vanilla .swift sources unchanged.
Template users should be able to use as much or as little templating as they like, and using templating on one declaration should not increase the cognitive burden of the rest of the code in the file.
Templating systems should nudge users towards using the least amount of templating necessary for their use-case.
Template sources should be self-explanatory, and understandable by developers who have never heard of swift-package-factory.
Template users should be able to stop using a templating system, and be able to assume responsibility for maintaining generated .swift files at any time.
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
}
}
Getting started
Check out the Examples directory to learn how to use SPF!
Features
factory extends the Swift language with three attributes:
@basis
Defines a sequence of tokens to iterate over when generating declarations from a template. It can be applied to a let binding, and it must be initialized with an array literal.
The declaration it is attached to will be removed from the generated .swift code, along with any associated comments and doccomments.
@matrix
Replicates the declaration it is attached to, along with any associated comments and doccomments. It takes @basis bindings or and/or inline array literals as arguments, with the name of the argument becoming the name of the loop variable. If more than one basis is given, @matrix zips them, and will discard trailing basis elements if their lengths differ.
@matrix can be applied to an associatedtype, actor, class, case, enum, extension, func, import, init, operator, precedence group, protocol, struct, subscript, typealias, let, or var declaration.
@retro
Downgrades a protocol with primary associated types to a protocol without any, and gates the two variants by #if swift(>=5.7). It can be applied to a protocol with at least one primary associatedtype.
@retro copies any comments and doccomments attached to the original protocol, and includes them in the generated #if blocks.
factory2022-12-17-afactoryis a structured, type-safe source generation tool. It is intended to be a replacement for (and improvement over) thegybtool!factoryis powered byswift-syntax, so it evolves with the toolchain. You cannot run it with the 5.6.2 release toolchain, because the 5.6.2 toolchain is too old and does not support the APIfactoryneeds to transform your sources safely.The current toolchain pin is:
swift-DEVELOPMENT-SNAPSHOT-2022-12-17-aSwift files generated by
factoryare still backwards compatible, in fact one of the main use cases offactoryis back-deployment.Platforms
SPF officially supports Linux and macOS.
Please note that on macOS, SPM sets the wrong
@rpathby default, so you will need to manually add a symlink tolib_InternalSwiftSyntaxParser.dylibinside your build artifacts directory.Overview
factorywas designed with the following goals in mind:Template files should look like normal
.swiftfiles, so highlighters and IDEs don’t freak out.Templates should be safe, and prohibit arbitrary string splicing or token substitutions.
Templates should work well with documentation comments.
Template syntax should be minimal, purely additive, and source generation tooling should accept and return vanilla
.swiftsources unchanged.Template users should be able to use as much or as little templating as they like, and using templating on one declaration should not increase the cognitive burden of the rest of the code in the file.
Templating systems should nudge users towards using the least amount of templating necessary for their use-case.
Template sources should be self-explanatory, and understandable by developers who have never heard of
swift-package-factory.Template users should be able to stop using a templating system, and be able to assume responsibility for maintaining generated
.swiftfiles at any time.In a nutshell:
Getting started
Check out the
Examplesdirectory to learn how to use SPF!Features
factoryextends the Swift language with three attributes:@basisDefines a sequence of tokens to iterate over when generating declarations from a template. It can be applied to a
letbinding, and it must be initialized with an array literal.The declaration it is attached to will be removed from the generated
.swiftcode, along with any associated comments and doccomments.@matrixReplicates the declaration it is attached to, along with any associated comments and doccomments. It takes
@basisbindings or and/or inline array literals as arguments, with the name of the argument becoming the name of the loop variable. If more than one basis is given,@matrixzips them, and will discard trailing basis elements if their lengths differ.@matrixcan be applied to anassociatedtype,actor,class,case,enum,extension,func,import,init,operator, precedence group,protocol,struct,subscript,typealias,let, orvardeclaration.@retroDowngrades a protocol with primary associated types to a protocol without any, and gates the two variants by
#if swift(>=5.7). It can be applied to aprotocolwith at least one primaryassociatedtype.@retrocopies any comments and doccomments attached to the originalprotocol, and includes them in the generated#ifblocks.